Multi-column IN / NOT IN subquery on Azure SQL data warehouse - azure-sqldw

Does Azure SQL Data Warehouse support a multi-column IN/NOT IN with subquery construct?
When running queries like:
select
*
from
schema_name.calendar
where
gregorian_date > '1998-01-01'
and gregorian_date < '1999-01-01'
and (yr_wk, day_of_wk) not in ( select yr_wk, day_of_wk from schema_name.calendar where week = 25 )
;
select
*
from
schema_name.calendar
where
gregorian_date > '1998-01-01'
and gregorian_date < '1999-01-01'
and (yr_wk, day_of_wk) in ( select yr_wk, day_of_wk from schema_name.calendar where week = 25 )
;
An error is received.
SQL Error [103010] [S0001]: Parse error at line: 7, column: 14: Incorrect syntax near ','.
com.microsoft.sqlserver.jdbc.SQLServerException: Parse error at line: 7, column: 14: Incorrect syntax near ','.
Is the workaround to rewrite the query into derived tables with inner or outer joins?
Single columns with IN / NOT IN subqueries do work:
select
*
from
schema_name.calendar
where
gregorian_date > '1998-01-01'
and gregorian_date < '1999-01-01'
and (yr_wk) not in ( select yr_wk from schema_name.calendar where week = 25 )
;
select
*
from
schema_name.calendar
where
gregorian_date > '1998-01-01'
and gregorian_date < '1999-01-01'
and (yr_wk) in ( select yr_wk from schema_name.calendar where week = 25 )
;

SQL Server has never supported this (handy) syntax. The workaround is to use an EXISTS/NOT EXISTS subquery.
eg
select *
from
schema_name.calendar c
where
gregorian_date > '1998-01-01'
and gregorian_date < '1999-01-01'
and not exists
(
select *
from schema_name.calendar
where week = 25
and yr_wk = c.yr_wk
and day_of_wk = c.yr_wk
)
;
David

Related

Redshift Error when executing the delete script with EXISTS function. The Select runs fine for this query

This Redshift query fails -
DELETE FROM TBL_1 stg
WHERE EXISTS (
WITH CCDA as (
SELECT
row_number() OVER (PARTITION BY emp_id,customer_id ORDER BY seq_num desc) rn
, *
FROM TBL_2
WHERE end_dt > (SELECT max(end_dt) FROM TBL_3)
)
SELECT emp_id,customer_id FROM CCDA WHERE rn = 1
AND stg.emp_id = CCDA.emp_id
AND stg.customer_id = CCDA.customer_id
);
Error: Invalid operation: syntax error at or near "stg"
However, the below query runs fine -
SELECT * FROM TBL_1 stg
WHERE EXISTS (
WITH CCDA as (
SELECT
row_number() OVER (PARTITION BY emp_id,customer_id ORDER BY seq_num desc) rn
, *
FROM TBL_2
WHERE end_dt > (SELECT max(end_dt) FROM TBL_3)
)
SELECT emp_id,customer_id FROM CCDA WHERE rn = 1
AND stg.emp_id = CCDA.emp_id
AND stg.customer_id = CCDA.customer_id
);
Am I missing something?
You cannot use an alias in a DELETE statement for the target table. "stg" cannot be used as the alias and this is why you are getting this error.
Also to reference other tables in a DELETE statement you need to use the USING clause.
See: https://docs.aws.amazon.com/redshift/latest/dg/r_DELETE.html
A quick stab of what this would look like (untested):
WITH CCDA as (
SELECT
row_number() OVER (PARTITION BY emp_id,customer_id ORDER BY seq_num desc) rn
, *
FROM TBL_2
WHERE end_dt > (SELECT max(end_dt) FROM TBL_3)
)
DELETE FROM TBL_1
USING CCDA
WHERE CCDA.rn = 1
AND TBL_1.emp_id = CCDA.emp_id
AND TBL_1.customer_id = CCDA.customer_id
;

Dax -- Dividing by aggregates from two different facts

I am trying to convert a piece of SQL to dax.
It only involves two tables, both facts and a common dimension attribute, Encounter.
I want to sum all charges by encounter and sum collections by encounter, filtered to only collections of TransactionRollup_Name = Contractual, TransactionTypeDescription = Adjustment, posted last month.
I will filter the System and Action <> Delete in the reporting client (powerbi or excel)
Once these are obtained I want the sum of contractual collections where the portion of contractual collections over total encounter charges is >= .9 and < 1
SQL:
DECLARE #startdate INT = 20181201
, #thrudate INT = 20181231
, #systemcode VARCHAR(1) = '1';
SELECT SUM(coll.Contractual)
FROM ( SELECT SUM(Amount) * -1 Contractual
, col.EncounterID
FROM
dwo.FactCollections col
JOIN dwo.DimTransactionCode_mds mds ON col.mds_TransactionID = mds.SK_TransactionKey
WHERE
mds.TransactionRollup_Name = 'Contractual'
AND mds.TransactionTypeDescription = 'Adjustment'
AND col.SystemID = TRY_CONVERT(INT, #systemcode)
AND col.Action <> 'Delete'
AND col.PostDateTime >= #startdate
AND col.PostDateTime <= #thrudate
GROUP BY col.EncounterID ) coll
JOIN ( SELECT EncounterID
, SUM(Amount) Charge
FROM dwo.FactCharges ldg
WHERE
ldg.SystemID = TRY_CONVERT(INT, #systemcode)
AND ldg.Action <> 'Delete'
GROUP BY ldg.EncounterID ) chg ON chg.EncounterID = coll.EncounterID
WHERE
chg.Charge <> 0
AND chg.Charge IS NOT NULL
AND coll.Contractual / chg.Charge >= .90
AND coll.Contractual / chg.Charge < 1.0;
Attempted Dax Measure:
90%-99.99% of Charges :=
CALCULATE (
'MeasureTable'[Sum of Contractual Adjustments],
FILTER (
'FactCollections',
DIVIDE (
'MeasureTable'[Sum of Contractual Adjustments],
'MeasureTable'[ChargeTotal]
)
>= .90
&& DIVIDE (
'MeasureTable'[Sum of Contractual Adjustments],
'MeasureTable'[ChargeTotal]
)
< 1.0
)
)
Charge := SUM ( 'FactCharges'[Amount] )
Sum of Contractual Adjustments :=
CALCULATE (
SUM ( FactCollections[Amount] ) * ( -1 ),
FILTER (
'Transaction Code',
'Transaction Code'[TransactionTypeDescription] = "Adjustment"
&& 'Transaction Code'[TransactionRollup_Name] = "Contractual"
)
)
Sample data on one encounter, per request.
Addendum
Going a different route with the dax, this gets me 1/2 way.
The summarizecolumns query gets me a result set that aggregates both charges and contractual collections up to the encounter and calculates the ratio of contractuals / charges.
The end result would need to filter this intermediate result set where
contractual / charge ratio is >= .9 and < 1
post dates for contractual collections should be filtered by reporting client filter context
All post dates for charges should be included, regardless of the post date filter context in the reporting client
I have no idea how to do that second part in dax though.
> EVALUATE SUMMARIZECOLUMNS (
> 'Encounter'[Encounter],
> "ChargeAmount", SUMX ( 'FactCharges', 'FactCharges'[Sum Charge Amount] ),
> "ContractualAmount", SUMX (
> 'FactCollections',
> CALCULATE (
> 'FactCollections'[Sum of Adjustments],
> 'Transaction Code'[TransactionRollup_Name] = "Contractual"
> )
> ),
> "Contractual : Charge", DIVIDE (
> SUMX (
> 'FactCollections',
> CALCULATE (
> 'FactCollections'[Sum of Adjustments] * -1,
> 'Transaction Code'[TransactionRollup_Name] = "Contractual"
> )
> ),
> SUMX ( 'FactCharges', 'FactCharges'[Sum Charge Amount] )
> ) )

Add Column Power BI from two column of different tables

I wanna add a column calculated from two column from different tables :
table 1 :
Date ; target;
19/10/2018; 52
table 2 :
Product; Duration;
P1; 1;
P2; 3;
P3; 4;
And i wanna have something like that
Product; Duration; New Column
P1; 1; (52/(1+3+4)*1)
P2; 3; (52/(1+3+4)*3)
P3; 4; (52/(1+3+4)*4)
With DAX try this as a new column for table2:
New Column = VALUES('table1'[target])/SUM(table2[ Duration])*'table2'[ Duration]
The VALUES function will work here because there is only one value in 'table1'[target]
When you expand table1 with more dates and targets like this:
You can use the LOOKUPVALUE function to retrieve the target for a specific date:
New Column =
LOOKUPVALUE ( Table1[target], Table1[Date], DATE ( 2018, 10, 19 ) )
/ SUM ( table2[ Duration] )
* 'table2'[ Duration]
Or the target form the latest date:
New Column =
LOOKUPVALUE ( Table1[target], Table1[Date], MAX ( 'Table1'[Date] ) )
/ SUM ( table2[ Duration] )
* 'table2'[ Duration]

From Select in doctrine 2

How do I do this in doctrine2 QB or DQL.
SELECT * FROM
(
select * from my_table order by timestamp desc
) as my_table_tmp
group by catid
order by nid desc
I think your query is the same as:
SELECT *
FROM my_table
GROUP BY catid
HAVING timestamp = MAX(timestamp)
ORDER BY nid DESC
;
If it is correct, then you should be able to do:
$qb->select('e')
->from('My\Entities\Table', 'e')
->groupBy('e.catid')
->having('e.timestamp = MAX(e.timestamp)')
->orderBy('nid', 'DESC')
;
Or, directly using DQL:
SELECT e
FROM My\Entities\Table e
GROUP BY e.catid
HAVING e.timestamp = MAX(e.timestamp)
ORDER BY e.nid DESC
;
Hope this helps and works! ;)

Need help on Regular expression to extract sql sub query

i am new to regx...i want to get the subquery from given query using regular expression.
For example i have query like following
Select * from (
select * from Table_A where ID = 90
UNION
select * from Table_B where ID = 90
) as SUBQUERY left join TABL_ABC abc ON (abc.id = SUBQUERY.id)
now i want my regular expression to match following lines only:
select * from Table_A where ID = 90
UNION
select * from Table_B where ID = 90
Please help me, Thank you in advance...
If it is a simple subquery without additional braces, you can just use this regexp
/\(\s*(select[^)]+)\)/i
<?php
$sql = 'Select * from ( select * from Table_A where ID = 90 UNION select * from Table_B where ID = 90 ) as SUBQUERY left join TABL_ABC abc ON (abc.id = SUBQUERY.id)';
if( preg_match('/\(\s*(select.+)\) as /iU', $sql, $matched ) ){
$subquery = trim( $matched[1] );
var_dump( $subquery );
}