Converting Postgres cross join lateral to SQL server code - sql-server

this is my current code:
SELECT c.id,
t.vaccinedate,
t.vaccine,
t.vaccinesource,
t.num
FROM child c
CROSS JOIN LATERAL ( VALUES (c.bcgsource,c.bcgdate,'bcg'::text,1), (c.opv0source,c.opv0date,'opv0'::text,2), (c.penta1source,c.penta1date,'penta1'::text,3), (c.pcv1source,c.pcv1date,'pcv1'::text,4), (c.rota1source,c.rota1date,'rota1'::text,5)) t(vaccinesource, vaccinedate, vaccine, num)
How to convert the same to SQL server code? Because I can't find Cross join lateral in SQL server.

We can try to use CROSS APPLY instead CROSS JOIN LATERAL in SQL server
SELECT c.id,
t.vaccinedate,
t.vaccine,
t.vaccinesource,
t.num
FROM child c
CROSS APPLY ( VALUES
(c.bcgsource, c.bcgdate, 'bcg', 1),
(c.opv0source, c.opv0date, 'opv0', 2),
(c.penta1source, c.penta1date, 'penta1', 3),
(c.pcv1source, c.pcv1date, 'pcv1', 4),
(c.rota1source, c.rota1date, 'rota1', 5)
) t(vaccinesource, vaccinedate, vaccine, num)

Related

three different tables nested with CTE and Join SQL functions

enter image description hereI have three tables that want to make some calculation based on. However, what I stated in the below did not work.
Could someone give me Any feedback?
Thank you,
formula:
(runnincost/total(gas_production of eacy year))*gas_production of each year)
as:
CTE c (id,filed,year_1,year_2,year_3)
as( select g.id, g.field,
(r.year_1/sum(g.year_1))*g.year_1 ,
(r.year_2/sum(g.year_2))*g.year_2 ,
(r.year_3/sum(g.year_3))*g.year_3 ,
from group_1 as g
inner join ref_fee as r
on r.id=g.id
group by g.field )
select c.id, c.filed,
c.year_1*b.year_1 as year_1,
c.year_2*b.year_2 as year_2,
c.year_3*b.year_3 as year_3
from c
inner join back b
on b.id=c.id
group by c.field;
"Did not work" is difficult to debug.
What is evident is that tables' aliases - in Oracle - can't have the AS keyword (columns can). When fixed, query looks like this:
WITH
c (id,
filed,
year_1,
year_2,
year_3)
AS
( SELECT g.id,
g.field,
(r.year_1 / SUM (g.year_1)) * g.year_1,
(r.year_2 / SUM (g.year_2)) * g.year_2,
(r.year_3 / SUM (g.year_3)) * g.year_3
FROM group_1 g INNER JOIN ref_fee r ON r.id = g.id
GROUP BY g.field)
SELECT c.id,
c.filed,
c.year_1 * b.year_1 AS year_1,
c.year_2 * b.year_2 AS year_2,
c.year_3 * b.year_3 AS year_3
FROM c INNER JOIN back b ON b.id = c.id
GROUP BY c.field;
I have no idea whether it'll work or not as I don't have your tables, nor I know what "calculations" you're about to perform.

SSIS merge join lacks row (and also How to simulate SSIS join with tsql query)

In my project I have a merge join transformation, that uses inner join. It is supposed to join the files lookup with the rest of the data flow. However, the join seems to not include some rows, with files, even though it should? I'm trying to simulate the join in tsql, but I seem to be doing it wrong as it shows me the missing rows.
Here are the outputs I'm trying to join
Input A:
SELECT *
FROM
tblExpense expense
OUTER APPLY(
SELECT TOP 1 *
FROM tblExpenseDtl Details
WHERE expense.intExpenseID = Details.intExpenseID
ORDER BY Details.sintLineNo
) details
WHERE
expense.dtUpdateDateTime > '2017-06-01'
ORDER BY expense.intExpenseID desc
Input B:
SELECT f.*
FROM dbo.tblExpense e
JOIN tblExpenseDtl d ON d.intExpenseID = e.intExpenseID
JOIN tblExpReceiptFile f ON f.intExpenseDtlID = d.intExpenseDtlID
WHERE
e.dtUpdateDateTime > '2017-06-01'
ORDER BY e.intExpenseID desc
And the sql query that I thought would produce the same result as my SSIS inner join
SELECT *
FROM
tblExpense expense
OUTER APPLY(
SELECT TOP 1 *
FROM tblExpenseDtl Details
WHERE expense.intExpenseID = Details.intExpenseID
ORDER BY Details.sintLineNo
) details
inner join ( SELECT f.*
FROM dbo.tblExpense e
JOIN tblExpenseDtl d ON d.intExpenseID = e.intExpenseID
JOIN tblExpReceiptFile f ON f.intExpenseDtlID = d.intExpenseDtlID
WHERE
e.dtUpdateDateTime > '2017-06-01'
ORDER BY e.intExpenseID desc
) innerJ
WHERE
expense.dtUpdateDateTime > '2017-06-01'
ORDER BY expense.intExpenseID desc
The join key in the SSIS is the expense.intExpenseID = e.intExpenseID.
Input A gives 1 row, with an expenseID=X, and input B gives 2 rows with an expenseID=X
How are you sorting data before merging it? According to this SSIS is sorting in different way than SQL Server (in most cases). Maybe there is a problem.
Edit: What type is intExpenseID?

Referencing Results of Multiple Temporary Tables in SQL Server

I’m using SQL Server 2008
I have joins written something like the following, where the first join is encapsulated in a ‘With as’ statement so that I can name the output table as ‘A’ and then reference the ‘A’ resulting table in the next select and Join seen beneath it.
This works perfectly fine. What I would like to do then is reference that second table for another select statement and join, but when I try to wrap it in a ‘With as’ statement as well, the editor does not accept it as legitimate syntax for the second instance of 'With as'.
How can I subset resulting tables to reference in further select and join statements? I do not have permission to write to the database, so I can not create permanent tables in the database.
Thank you.
With A as
(
SELECT POL.[COMPANY_CODE]
,POL.[POLICY_NUMBER]
,POL.[STATUS_CODE]
,POL.ORIG_CLIENT_NUM
,TA.LINE
FROM [SamsReporting].[dbo].[POLICY] POL
Left join [SamsReporting].[dbo].[Transact] TA
ON TA.POLICY_NUMBER = POL.POLICY_NUMBER and TA.BASE_Account = 'B'
)
Select PM.POLICY_NUMBER
,A.[COMPANY_CODE]
,A.[POLICY_NUMBER]
,A.[Policy Status]
,eApp.SourceCode
From A
Left Join Web.dbo.Pmetrics PM on A.POLICY_NUMBER=PM.POLICY_NUMBER
Left Outer Join DDP.pol.eAppStaging eApp
on A.POLICY_NUMBER=eApp.PolicyNumber
where eApp.SourceCode = 'HAQ' or eApp.SourceCode = 'PLS'
Common Table Expressions (CTEs) can build upon each other as you would like. For example, you can do this:
WITH CTE1 AS (SELECT * FROM Table 1)
, CTE2 AS (SELECT * FROM CTE1)
, CTE3 AS (SELECT * FROM CTE2)
You only need the WITH statement for the first CTE. After that just use the CTE name, as in my example.
Hope that helps,
Ash
Sounds like a syntax issue to me. Google CTE (Common Table Expression) and review some examples of how they are formed.
With A as
(SELECT POL.[COMPANY_CODE]
,POL.[POLICY_NUMBER]
,POL.[STATUS_CODE]
,POL.ORIG_CLIENT_NUM
,TA.LINE
FROM [SamsReporting].[dbo].[POLICY] POL
Left join [SamsReporting].[dbo].[Transact] TA
ON TA.POLICY_NUMBER = POL.POLICY_NUMBER and TA.BASE_Account = 'B'),
B as (
Select PM.POLICY_NUMBER
,A.[COMPANY_CODE]
,A.[POLICY_NUMBER]
,A.[Policy Status]
,eApp.SourceCode
From A
Left Join Web.dbo.Pmetrics PM on A.POLICY_NUMBER=PM.POLICY_NUMBER
Left Outer Join DDP.pol.eAppStaging eApp
on A.POLICY_NUMBER=eApp.PolicyNumber
where eApp.SourceCode = 'HAQ' or eApp.SourceCode = 'PLS')
Select *
From B -- inner join some table
where some condition = 1

Any other ways to change "With As" for mariadb

WITH KPILibHier (kpilib_code,parent_code,kpi_name, depth, iscategory)
AS ( SELECT K.kpilib_code, K.parent_code, K.kpi_name_en, K.kpi_depth, K.iscategory
FROM TPMDPERIODKPILIB K
INNER JOIN TPMDPERIODKPI PK ON PK.period_code = K.period_code
UNION ALL
SELECT A.kpilib_code, A.parent_code, A.kpi_name_en, A.kpi_depth, A.iscategory
FROM TPMDPERIODKPILIB A
INNER JOIN KPILibHier AS B ON A.kpilib_code = B.parent_code )
SELECT DISTINCT Z.kpi_name AS libname, Z.kpilib_code AS libcode,
Z.parent_code AS pcode, Z.depth, Z.iscategory, PK.target
FROM KPILibHier Z
LEFT JOIN TPMDPERIODKPILIB KPI
ON KPI.kpilib_code = Z.kpilib_code
LEFT JOIN TPMDPERIODKPI PK
ON PK.period_code = KPI.period_code
ORDER BY Z.depth, Z.kpi_name
This is my code.
I could run it in SQL Server,
But now i have to use Mariadb,
and Mariadb doesn't use "WITH AS".
So is there any other way to change this code for the same result?
As we can see, there's "INNER JOIN KPILibHier" too inside the CTE,
So I couldn't make ordinary subquery as usual.
Just moving the contents of the CTE to a derived table should provide something usable. Something like;
SELECT DISTINCT Z.kpi_name AS libname, Z.kpilib_code AS libcode,
Z.parent_code AS pcode, Z.depth, Z.iscategory, PK.target
FROM
( SELECT K.kpilib_code, K.parent_code, K.kpi_name_en AS kpi_name, K.kpi_depth AS depth, K.iscategory
FROM TPMDPERIODKPILIB K
INNER JOIN TPMDPERIODKPI PK ON PK.period_code = K.period_code
UNION ALL
SELECT A.kpilib_code, A.parent_code, A.kpi_name_en, A.kpi_depth, A.iscategory
FROM TPMDPERIODKPILIB A
) z
INNER JOIN z AS B ON A.kpilib_code = B.parent_code
LEFT JOIN TPMDPERIODKPILIB KPI
ON KPI.kpilib_code = Z.kpilib_code
LEFT JOIN TPMDPERIODKPI PK
ON PK.period_code = KPI.period_code
ORDER BY Z.depth, Z.kpi_name

TSQL optimizing code for NOT IN

I inherit an old SQL script that I want to optimize but after several tests, I must admit that all my tests only creates huge SQL with repetitive blocks. I would like to know if someone can propose a better code for the following pattern (see code below). I don't want to use temporary table (WITH). For simplicity, I only put 3 levels (table TMP_C, TMP_D and TMP_E) but the original SQL have 8 levels.
WITH
TMP_A AS (
SELECT
ID,
Field_X
FROM A
TMP_B AS(
SELECT DISTINCT
ID,
Field_Y,
CASE
WHEN Field_Z IN ('TEST_1','TEST_2') THEN 'CATEG_1'
WHEN Field_Z IN ('TEST_3','TEST_4') THEN 'CATEG_2'
WHEN Field_Z IN ('TEST_5','TEST_6') THEN 'CATEG_3'
ELSE 'CATEG_4'
END AS CATEG
FROM B
INNER JOIN TMP_A
ON TMP_A.ID=TMP_B.ID),
TMP_C AS (
SELECT DISTINCT
ID,
CATEG
FROM TMP_B
WHERE CATEG='CATEG_1'),
TMP_D AS (
SELECT DISTINCT
ID,
CATEG
FROM TMP_B
WHERE CATEG='CATEG_2' AND ID NOT IN (SELECT ID FROM TMP_C)),
TMP_E AS (
SELECT DISTINCT
ID,
CATEG
FROM TMP_B
WHERE CATEG='CATEG_3'
AND ID NOT IN (SELECT ID FROM TMP_C)
AND ID NOT IN (SELECT ID FROM TMP_D))
SELECT * FROM TMP_C
UNION
SELECT * FROM TMP_D
UNION
SELECT * FROM TMP_E
Many thanks in advance for your help.
First off, select DISTINCT will prevent duplicates from the result set, so you are overworking the condition. By adding the "WITH" definitions and trying to nest their use makes it more confusing to follow. The data is ultimately all coming from the "B" table where also has key match in "A". Lets start with just that... And since you are not using anything from the (B)Field_Y or (A)Field_X in your result set, don't add them to the mix of confusion.
SELECT DISTINCT
B.ID,
CASE WHEN B.Field_Z IN ('TEST_1','TEST_2') THEN 'CATEG_1'
WHEN B.Field_Z IN ('TEST_3','TEST_4') THEN 'CATEG_2'
WHEN B.Field_Z IN ('TEST_5','TEST_6') THEN 'CATEG_3'
ELSE 'CATEG_4'
END AS CATEG
FROM
B JOIN A ON B.ID = A.ID
WHERE
B.Field_Z IN ( 'TEST_1', 'TEST_2', 'TEST_3', 'TEST_4', 'TEST_5', 'TEST_6' )
The where clause will only include those category qualifying values you want and still have the results per each category.
Now, if you actually needed other values from your "Field_Y" or "Field_X", then that would generate a different query. However, your Tmp_C, Tmp_D and Tmp_E are only asking for the ID and CATEG columns anyhow.
This may perform better
SELECT DISTINCT B.ID, 'CATEG_1'
FROM
B JOIN A ON B.ID = A.ID
WHERE
B.Field_Z IN ( 'TEST_1', 'TEST_2')
UNION
SELECT DISTINCT B.ID, 'CATEG_2'
FROM
B JOIN A ON B.ID = A.ID
WHERE
B.Field_Z IN ( 'TEST_3', 'TEST_4')
...

Resources