Microsoft SQL Server , view transformation - sql

Is it possible to transform the following view :
to this structure ?
I've tried with cross join but I have no idea how to make a condition based on column name.

You need APPLY instead of JOIN to be able to access outer columns
SELECT t.Date, v.[1], v.[2], v.number
FROM Table t
CROSS APPLY (VALUES
(t.[1], CAST(NULL AS int), 1),
(NULL, t.[2], 2)
) v ([1], [2], number)

Related

How to convert this query for Spark SQL

I'm trying to convert an SQL Server query to execute it into a Notebook, but I can't figure out how to convert a "CROSS APPLY" into something that Spark can understand.
Here is my SQL Server query :
WITH Benef as (
SELECT DISTINCT
IdBeneficiaireSource
,Adress
FROM
UPExpBeneficiaryStaging
)
-------- Split Adress --------
,AdresseBenefTemp1 as (
SELECT
IdBeneficiaireSource
,REPLACE(REPLACE(Adress, char(10), '|'), char(13), '|') as AdresseV2
FROM
Benef
)
,AdresseBenefTemp2 as (
SELECT
IdBeneficiaireSource
,value as Adresse
,ROW_NUMBER() OVER(PARTITION BY IdBeneficiaireSource ORDER BY (SELECT NULL)) as LigneAdresse
FROM
AdresseBenefTemp1
CROSS APPLY string_split(AdresseV2, '|')
)
,AdresseBenefFinal as (
SELECT DISTINCT
a.IdBeneficiaireSource
,b.Adresse as Adresse_1
,c.Adresse as Adresse_2
,d.Adresse as Adresse_3
FROM
AdresseBenefTemp2 as a
LEFT JOIN AdresseBenefTemp2 as b on b.IdBeneficiaireSource = a.IdBeneficiaireSource AND b.LigneAdresse = 1
LEFT JOIN AdresseBenefTemp2 as c on c.IdBeneficiaireSource = a.IdBeneficiaireSource AND c.LigneAdresse = 2
LEFT JOIN AdresseBenefTemp2 as d on d.IdBeneficiaireSource = a.IdBeneficiaireSource AND d.LigneAdresse = 3
)
-------------------------------
SELECT
a.IdBeneficiaireSource
,Adresse_1
,Adresse_2
,Adresse_3
FROM
AdresseBenefFinal
(This query split an address field into three address fields)
When I run it into a Notebook, it says that "CROSS APPLY" is not correct.
Thanks.
Correct me if I'm wrong, but the cross apply string_split is basically a cross join for each entry in the resulting split.
In Spark you're able to use an explode for this (https://docs.databricks.com/sql/language-manual/functions/explode.html). So you should be able to add another CTE in between where you explode the splitted (https://docs.databricks.com/sql/language-manual/functions/split.html) results from AddresseV2 by '|'.

Why Row_Number in a view gives a nullable column

I have a view using a CTE and I want use a row number to simulate a key for my edmx in Visual Studio
ALTER VIEW [dbo].[ViewLstTypesArticle]
AS
WITH cte (IdTypeArticle, IdTypeArticleParent, Logo, Libelle, FullLibelle, Racine) AS
(
SELECT
f.Id AS IdTypeArticle, NULL AS IdParent,
f.Logo, f.Libelle,
CAST(f.Libelle AS varchar(MAX)) AS Expr1,
f.Id AS Racine
FROM
dbo.ArticleType AS f
LEFT OUTER JOIN
dbo.ArticleTypeParent AS p ON p.IdTypeArticle = f.Id
WHERE
(p.IdTypeArticleParent IS NULL)
AND (f.Affichable = 1)
UNION ALL
SELECT
f.Id AS IdTypeArticle, p.IdTypeArticleParent,
f.Logo, f.Libelle,
CAST(parent.Libelle + ' / ' + f.Libelle AS varchar(MAX)) AS Expr1,
parent.Racine
FROM
dbo.ArticleTypeParent AS p
INNER JOIN
cte AS parent ON p.IdTypeArticleParent = parent.IdTypeArticle
INNER JOIN
dbo.ArticleType AS f ON f.Id = p.IdTypeArticle
)
SELECT
*,
ROW_NUMBER() OVER (ORDER BY FullLibelle) AS Id
FROM
(SELECT
IdTypeArticle, IdTypeArticleParent, Logo, Libelle,
FullLibelle, Racine
FROM cte) AS CTE1
When I look in properties of column I see Id bigint ... NULL
And my edmx exclude this view cause don't find a column can be used to key
When I execute my view ID have no null. I've all my row number.
If someone encounter this problem and resolved it ... Thanks
SQL Server generally thinks that columns are NULL-able in views (and when using SELECT INTO).
You can convince SQL Server that this is not the case by using ISNULL():
select *,
ISNULL(ROW_NUMBER() over(ORDER BY FullLibelle), 0) as Id
from . . .
Note: This works with ISNULL() but not with COALESCE() which otherwise has very similar functionality.

Trouble with Pivot table

First time posting. I am very new to pivot tables and have looked up several answers on how to create them, but I cant seem to get mine to work. Is a pivot table the correct way to go?
What I'm trying to do is take all the columns and make them rows and the rows become the columns. Basically turn the table 90 degrees. See Image.
Thanks
Image of Base query results and results I'm trying to get
Base query
SELECT dbo.EstimateDetails.EstimateDetailID,
dbo.EstimateDetails.QtyOrdered,
dbo.EstimateDetails.NetPrice,
dbo.EstimateDetails.ExtendedPrice,
dbo.EstimateDetails.EstimateID,
dbo.UserDefined_Custom.UserDefined1,
dbo.UserDefined_Custom.UserDefined2,
dbo.EstimateDetails.OrdUOMID,
dbo.Estimate.EstimateNo,
dbo.EstimateDetails.[LineNo] AS Line
FROM dbo.EstimateDetails
INNER JOIN dbo.Estimate
ON dbo.EstimateDetails.EstimateID = dbo.Estimate.EstimateID
LEFT OUTER JOIN dbo.UserDefined_Custom
ON dbo.EstimateDetails.ItemSpecID = dbo.UserDefined_Custom.ItemSpecID
where dbo.EstimateDetails.EstimateID = 141865
Where I'm at now with no luck.
Results with Pivot attempt
Select
Pvt.[1], Pvt.[2], Pvt.[3], Pvt.[4],Pvt.[5],Pvt.[6]
from
(SELECT dbo.EstimateDetails.EstimateDetailID,
dbo.EstimateDetails.QtyOrdered,
dbo.EstimateDetails.NetPrice,
dbo.EstimateDetails.ExtendedPrice,
dbo.EstimateDetails.EstimateID,
dbo.UserDefined_Custom.UserDefined1,
dbo.UserDefined_Custom.UserDefined2,
dbo.EstimateDetails.OrdUOMID,
dbo.Estimate.EstimateNo,
dbo.EstimateDetails.[LineNo] AS Line
FROM dbo.EstimateDetails
INNER JOIN dbo.Estimate
ON dbo.EstimateDetails.EstimateID = dbo.Estimate.EstimateID
LEFT OUTER JOIN dbo.UserDefined_Custom
ON dbo.EstimateDetails.ItemSpecID = dbo.UserDefined_Custom.ItemSpecID
where dbo.EstimateDetails.EstimateID = 141865
) AS Src
PIVOT
(
Max(EstimateDetailID)
for Line in ([1], [2], [3], [4],[5],[6])
) AS Pvt
You need a full transpose, so first unpivot then pivot. Note that you need to convert all columns to a common type.
I personally tend to prefer using CROSS APPLY instead of UNPIVOT, I find it much clearer.
You should also use aliases for tables, it makes the query much easier to write and read.
Select
Pvt.Col AS Line, Pvt.[1], Pvt.[2], Pvt.[3], Pvt.[4],Pvt.[5],Pvt.[6]
from (
SELECT
ed.[LineNo] AS Line,
Upvt.Col,
Upvt.value
FROM dbo.EstimateDetails AS ed
INNER JOIN dbo.Estimate AS e
ON ed.EstimateID = e.EstimateID
LEFT OUTER JOIN dbo.UserDefined_Custom AS udc
ON ed.ItemSpecID = udc.ItemSpecID
CROSS APPLY (
('EstimateDetailID', CAST(ed.EstimateDetailID AS varchar(50)),
('QtyOrdered', CAST(ed.QtyOrdered AS varchar(50)),
('NetPrice', CAST(ed.NetPrice AS varchar(50)),
('ExtendedPrice', CAST(ed.ExtendedPrice AS varchar(50)),
('EstimateID', CAST(ed.EstimateID AS varchar(50)),
('UserDefined1', CAST(udc.UserDefined1 AS varchar(50)),
('UserDefined2', CAST(udc.UserDefined2 AS varchar(50)),
('OrdUOMID', CAST(ed.OrdUOMID AS varchar(50)),
('EstimateNo', CAST(e.EstimateNo AS varchar(50))
) AS Upvt(Col, Value)
where ed.EstimateID = 141865
) AS Src
PIVOT
(
Max(Value)
for Line in ([1], [2], [3], [4], [5], [6])
) AS Pvt
To be honest, looking at it now, I realize you really are just transposing it for display, so the column names don't really make sense (Line has the columna names in it for example). I'd advise you to do this in a client application, T-SQL is really not the place for this.

How to unpivot the table with column Names

I have two tables with similar records. I have the result as follows:
using the following query
Select
New.ParentId
,New.FatherFirstName
,New.FatherLastName
from ParentsUpdationDetails New
where New.parentId=15999
union all
select
Old.ParentId
,Old.FatherFirstName
,Old.FatherLastName
from parents Old
where Old.parentId=15999
I need to unpivot and want the following output:
you should be able to handle this using CROSS APPLY with a few Table Value Constructors and combining them using INNER JOIN
when you use Cross Apply with (VALUES (Field1), (Field2)) it acts similar to UNPIVOT in that you get a row for each Field you list in your TVC
SELECT ca.Field, ca.New, lj.Old
FROM ParentsUpdationDetails new
CROSS APPLY (
VALUES ('ParentID', CAST(ParentID AS VARCHAR)), -- All datatypes must match
('FatherFirstName', FatherFirstName),
('FatherLastName', FatherLastName)
) ca(Field, New)
INNER JOIN (
SELECT ParentID, Field, Old
FROM Parents old
CROSS APPLY (
VALUES ('ParentID', CAST(ParentID AS VARCHAR)), -- All datatypes must match
('FatherFirstName', FatherFirstName),
('FatherLastName', FatherLastName)
) ca(Field, Old)
) lj ON new.ParentID = lj.ParentID AND ca.Field = lj.Field
WHERE new.ParentID = 15999
be aware that you will be converting non varchar datatypes to varchars in order for this to work

Using both CROSS APPLY and INNER JOIN in the same query

I'm attempting to use both Left Join and Cross Apply in the same query and running into difficulties.
SELECT vAH.TagName, vAH.EventSTamp, -123 Value, vAH.Description,
-- Ack.DateTime, Ack.UserFullName as AckUser, Ack.Description as AckComment,
LEFT(vAH.TagName,9) + CONVERT(nvarchar(30),LLC.StartDateTime,113) as ObjName
FROM WWALMDBArchived.dbo.v_AlarmHistory vAH
--CROSS APPLY (
-- SELECT TOP 1 EventStamp as DateTime, UserFullName, Description
-- FROM WWALMDBArchived.dbo.v_AlarmHistory vAH
-- WHERE TagName = vAH.TagName
-- AND EventStamp > vAH.EventStamp
-- AND AlarmState IN ('ACK_RTN','ACK_ALM')
-- ORDER BY DateTime, UserFullName, Description DESC
-- ) Ack
INNER JOIN CPMS.dbo.LotListConfig LLC
ON vAH.EventStamp >= LLC.StartDateTime
AND vAH.EventStamp <= LLC.EndDateTime
WHERE vAH.TagName LIKE #LineNumber + '%.Action_Alarm_ALM'
AND LLC.LineNumber = #LineNumber
AND LLC.LotNumber = #LotNumber
AND vAH.AlarmState = 'UNACK_ALM'
Essentially what I am doing is getting the boundary information from the LotListConfig table, getting the initial alarm information from v_AlarmHistory, and using the Cross Apply to get some subsequent alarm information from the v_AlarmHistory table.
The query above returns the records I would expect, but uncommenting the Cross Apply causes no records to return. There's an interaction of some kind happening between the Inner Join and the Cross Apply that I'm missing.
Anyone?
Nevermind.
My query above is using the same table shortcut (vAH) in both the main query and the CROSS APPLY query. Deleting the vAH inside the Cross Apply resolves the issue.