How to get multiple values from a singe query in sql - sql

I have a query like:
SELECT NUM,
PARAM_1
FROM STOCK_CARD_PARAMETER WITH(NOLOCK)
WHERE FK_STOCK_CARD IN (SELECT FK_sTOCK_CARD
FROM STOCK_BARCODE WITH(NOLOCK)
WHERE BARCODE = '2002002232364' )
And it returns:
NUM PARAM_1
1 İNDİRİMSİZ
2 SEZON
3 UNISEXYETISKIN
I have to get a result like that. (side by side)
İNDİRİMSİZ SEZON UNISEXYETISKIN
To do this, I execute almost the same query 2 times like this:
INDIRIM = (SELECT PARAM_1
FROM STOCK_CARD_PARAMETER WITH(NOLOCK)
WHERE FK_STOCK_CARD IN (SELECT FK_sTOCK_CARD
FROM STOCK_BARCODE WITH(NOLOCK)
WHERE BARCODE = #BARKOD AND NUM = 1)),
STATU = ( SELECT PARAM_1
FROM STOCK_CARD_PARAMETER WITH(NOLOCK)
WHERE FK_STOCK_CARD IN (SELECT FK_sTOCK_CARD
FROM STOCK_BARCODE WITH(NOLOCK)
WHERE BARCODE = #BARKOD AND NUM = 2))
NUM column is the key here. How do I make this two query combined and get the result side by side?

Using PIVOT
SELECT [1], [2], [3]
FROM
(SELECT NUM, PARAM_1
FROM table) AS SourceTable
PIVOT
(
MAX(PARAM_1)
FOR NUM IN ([1], [2], [3])
) AS PivotTable;
Sample data with output
WITH C(NUM, PARAM_1) AS(
SELECT 1 , N'İNDİRİMSİZ' UNION ALL
SELECT 2 , N'SEZON' UNION ALL
SELECT 3 , N'UNISEXYETISKIN'
)
SELECT [1], [2], [3]
FROM
(SELECT NUM, PARAM_1
FROM C) AS SourceTable
PIVOT
(
MAX(PARAM_1)
FOR NUM IN ([1], [2], [3])
) AS PivotTable;
Output
İNDİRİMSİZ SEZON UNISEXYETISKIN

Related

Pivot data T-SQL

I have the following table:
I want to pivot it to the following table:
I tried to work with the following example:
https://www.sqlshack.com/dynamic-pivot-tables-in-sql-server/
But in this case a SUM operator is mandatory.
I don't want to use the SUM operator for my data.
What would be the best approach to go.
Eventually I want to use the data again, I want to prevent that I need to make a lot of "left join" statements like the following:
select table_a.Cat,one.number as number1, one.namevalue as Name1, two.number as number2, two.namevalue as name2
from table_a
left outer join (
select *
from #temp
where numbercat = 'number1'
) as one on table_a.cat = one.cat
left outer join (
select *
from #temp
where numbercat = 'number2'
) as two on table_a.cat = two.cat
I am able to unpivot the numbercat & number with the following code:
select *
from
(
select cat, numbercat, number
from #input
) src
pivot
(
min(number)
for numbercat in ([1], [2], [3])
) piv;
What should I do to also incorporate the Namecat & namevalue data?
I find that conditional aggregation is usually simpler and more versatile than pivot:
select cat,
max(case when numbercat = 'number1' then number end) as number1,
max(case when numbercat = 'number2' then number end) as number2,
max(case when namecat = 'name1' then name end) as name1,
max(case when namecat = 'name2' then name end) as name2
from #temp
group by cat;

how to find first, second and third largest values from different columns in SQL

Hi I have a table with columns J1,J2,J3,J4,J5,J6,J7. I want to find the largest 3 values from these columns as L1,L2,L3.
I tried the below query to find the first largest
SELECT (
SELECT Max(v) FROM (
VALUES
([J1]), ([J2]),
([J3]), ([J4]),
([J5]), ([J6]),
([J7])
) AS value(v)
) as [L1]FROM dbo.JTable
If your table has a PK, say id, then you can use a query that employees UNPIVOT:
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY Val) AS rn
FROM JTable
UNPIVOT (
Val FOR Col IN (J1, J2, J3, J4, J5, J6, J7)) AS unpvt) AS t
WHERE t.rn <= 3
If you want one row per id, then you can use PIVOT to undo the UNPIVOT operation:
SELECT id, [1], [2], [3]
FROM (
SELECT id, Val, rn
FROM (
SELECT id, Val, Col,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY Val) AS rn
FROM JTable
UNPIVOT (
Val FOR Col IN (J1, J2, J3, J4, J5, J6, J7)) AS unpvt) AS t
WHERE t.rn <= 3) AS src
PIVOT (
MAX(Val) FOR rn IN ([1], [2], [3])) AS pvt

How to store result of sql query in variable?

I have the following query:
with cte as
(SELECT top 10 [1],[2]
FROM [tbl_B] where [2] > '2000-01-01' and Status_7 = 0 and Status_8 = 1
ORDER BY [2])
,
CTE1 AS
( select [1], row_number() over (order by [2]) as rn
from CTE
)
select [1] from CTE1 where rn = '10'
how can I put this into a variable to compare it to another query result?
If i use set #123 = (above query) it gives errors.
with cte as
(
SELECT top 10 [1],[2]
FROM [tbl_B]
where [2] > '2000-01-01' and Status_7 = 0 and Status_8 = 1
ORDER BY [2]
)
,CTE1 AS
(
select [1], row_number() over (order by [2]) as rn
from CTE
)
select #123 = [1] from CTE1 where rn = '10'
with cte as
(SELECT top 10 [1],[2]
FROM [tbl_B] where [2] > '2000-01-01' and Status_7 = 0 and Status_8 = 1
ORDER BY [2])
,
CTE1 AS
( select [1], row_number() over (order by [2]) as rn
from CTE
)
select #123 = [1] from CTE1 where rn = '10'
You can use a table variable to store the CTE's result set. For example:
declare #table_var table (id int, col1 varchar(50));
; with CTE as
(
... your definition here ...
)
insert #table_var
(id, col1)
select id
, col1
from CTE
Comparing this with another set can be done with a full outer join:
select coalesce(t1.id, t2.id) as id
, coalesce(t1.col1, t2.col1) as col1
, case
when t1.id is null then 'Missing in t1'
when t2.id is null then 'Missing in t2'
when isnull(t1.col1,'') <> isnull(t2.col1,'') then 'Col1 is different'
else 'Identical'
end as Difference
from #table_var1 t1
full outer join
#table_var2 t2
on t1.id = t2.id

SQL- pad results with extra rows

I have a group of records that have a "Store" column. I need to basically split the result sets into groups of 13 records, creating blank rows to pad out each store to have 13 rows.
For simplicity, lets say I need groups of 4 records.
Example, given the below table:
-----------------
Store Name
-----------------
A John
A Bill
B Sam
C James
C Tim
C Chris
D Simon
D Phil
I need the results to look like:
-----------------
Store Name
-----------------
A John
A Bill
A
B Sam
B
B
C James
C Tim
C Chris
D Simon
D Phil
D
Is this at all possible with pure SQL? There are never going to be more than 3 rows for each store.
SQL Fiddle
Try this one -
DDL:
SET STATISTICS IO ON;
IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL
DROP TABLE #temp
CREATE TABLE #temp
(
Store CHAR(1)
, Name VARCHAR(10)
)
INSERT INTO #temp (Store, Name)
VALUES
('A', 'John'), ('A', 'Bill'),
('B', 'Sam'), ('C', 'James'),
('C', 'Tim'), ('C', 'Chris'),
('D', 'Simon'), ('D', 'Phil')
Queries:
DevArt #1:
;WITH cte AS
(
SELECT
Store
, Name
, rn = ROW_NUMBER() OVER (PARTITION BY Store ORDER BY (SELECT 1))
FROM #temp
)
SELECT t.Store, Name = ISNULL(t3.Name, '')
FROM (
SELECT DISTINCT Store
FROM cte
) t
CROSS JOIN (SELECT rn = 1 UNION ALL SELECT 2 UNION ALL SELECT 3) t2
LEFT JOIN cte t3 ON t2.rn = t3.rn AND t.Store = t3.Store
DevArt #2:
SELECT t2.Store, Name = ISNULL(t3.Name, '')
FROM (
SELECT *
FROM (
SELECT Store, r = COUNT(1)
FROM #temp
GROUP BY Store
) t
CROSS APPLY (
VALUES (r), (r+1), (r+2)
) t2 (x)
) t2
LEFT JOIN #temp t3 ON t2.Store = t3.Store AND t2.x = t2.r
WHERE t2.x < 4
Alexander Fedorenko:
;WITH cte AS
(
SELECT DISTINCT Store
FROM #temp
)
SELECT o.Store, o.name
FROM cte s
CROSS APPLY (
SELECT TOP 3 x.Store, x.name
FROM (
SELECT s2.Store, s2.name
FROM #temp s2
WHERE s.Store = s2.Store
UNION ALL
SELECT s.Store, ''
UNION ALL
SELECT s.Store, ''
) x
) o
ErikE:
SELECT Store, Name
FROM (
SELECT
x.Store
, x.Name
, s = ROW_NUMBER() OVER (PARTITION BY x.Store ORDER BY x.s)
FROM #temp t
CROSS APPLY (
VALUES
(Store, Name, 0),
(Store, '', 1),
(Store, '', 1)
) x (Store, Name, S)
) z
WHERE s <= 3
ORDER BY Store
AmitSingh:
SELECT t.Store, Name = COALESCE(
(
SELECT name
FROM (
SELECT
row1 = ROW_NUMBER() OVER (PARTITION BY Store ORDER BY Store)
, *
FROM #temp
) c
WHERE t.[row] = c.row1
AND t.Store = c.Store
)
, '')
FROM
(
SELECT
[Row] = ROW_NUMBER() OVER (PARTITION BY a.Store ORDER BY a.Store)
, a.Store
FROM (
SELECT Store
FROM #temp
GROUP BY Store
) a
, (
SELECT TOP 3 Store
FROM #temp
) b
) t
Andriy M #1:
;WITH ranked AS
(
SELECT
Store
, Name
, rnk = ROW_NUMBER() OVER (PARTITION BY Store ORDER BY 1/0)
FROM #temp
)
, pivoted AS
(
SELECT
Store
, [1] = ISNULL([1], '')
, [2] = ISNULL([2], '')
, [3] = ISNULL([3], '')
FROM ranked
PIVOT (
MAX(Name)
FOR rnk IN ([1], [2], [3])
) p
)
, unpivoted AS
(
SELECT
Store
, Name
FROM pivoted
UNPIVOT (
Name FOR rnk IN ([1], [2], [3])
) u
)
SELECT *
FROM unpivoted
Andriy M #2:
;WITH ranked AS
(
SELECT
Store
, Name
, rnk = ROW_NUMBER() OVER (PARTITION BY Store ORDER BY 1/0)
FROM #temp
)
, padded AS
(
SELECT
Store
, Name
FROM ranked
PIVOT (
MAX(Name)
FOR rnk IN ([1], [2], [3])
) p
CROSS APPLY (
VALUES
(ISNULL([1], '')),
(ISNULL([2], '')),
(ISNULL([3], ''))
) x (Name)
)
SELECT *
FROM padded
Output:
Store Name
----- ----------
A John
A Bill
A
B Sam
B
B
C James
C Tim
C Chris
D Simon
D Phil
D
Statistics:
Query Presenter Scans Logical Reads
------------------- ----- -------------
DevArt #1 3 41
DevArt #2 2 9
Alexander Fedorenko 4 5
ErikE 1 1
AmitSingh 22 25
Andriy M #1 1 1
Andriy M #2 1 1
Query cost:
Extended statistics:
Execution statistics:
Query plan (from dbForge Studio for MS SQL):
Select t.store_id,Coalesce((Select Name from (
Select row_Number() Over(Partition by store_id order by store_id) as row1, * from stores)c
where t.row=c.row1 and t.store_id=c.store_id),'') as cfgg
from
(Select row_Number() Over(Partition by a.store_id order by a.store_id) as row,
a.store_id from
(Select store_id from stores group by store_id) a ,(Select top 3 store_id from stores)b
) t
SQL Fiddle Demo
One more option with APPLY operator
;WITH cte AS
(
SELECT store_id
FROM stores
GROUP BY store_id
)
SELECT o.store_id, o.name
FROM cte s CROSS APPLY (
SELECT TOP 3 x.store_id, x.name
FROM (
SELECT s2.store_id, s2.name
FROM stores s2
WHERE s.store_id = s2.store_id
UNION ALL
SELECT s.store_id, ''
UNION ALL
SELECT s.store_id, ''
) x
) o
Demo on SQLFiddle
Here's a query that works (SQL Server 2008 and up, can be fixed to work in 2005):
SELECT Store, Name
FROM (
SELECT
X.Store, X.Name, R = Row_Number() OVER (PARTITION BY X.Store ORDER BY X.S)
FROM
#temp T
CROSS APPLY (VALUES
(Store, Name, 0), (Store, '', 1), (Store, '', 1)
) X (Store, Name, S)
) Z
WHERE R <= 3
ORDER BY Store
;
According to SET STATISTICS IO ON;, here are performance statistics (all have negligible CPU at this low number of rows, perhaps more rows would help determine the best performer):
Query Presenter Scans Logical Reads
------------------- ----- -------------
ErikE 1 1
Alexander Fedorenko 4 5
Devart 3 41
AmitSingh 22 25
My query does not preserve the "original" ordering of the names for each store, however that is not a flaw because there is no concept of ordering in a relational database table. You must supply a column to order by if you want to preserve a particular sequence.
Yet another option, this time using PIVOT and UNPIVOT:
WITH ranked AS (
SELECT
store_id,
name,
rnk = ROW_NUMBER() OVER (PARTITION BY store_id ORDER BY 1/0)
FROM stores
),
pivoted AS (
SELECT
store_id,
[1] = ISNULL([1], ''),
[2] = ISNULL([2], ''),
[3] = ISNULL([3], '')
FROM ranked
PIVOT (
MAX(name) FOR rnk IN ([1], [2], [3])
) p
),
unpivoted AS (
SELECT
store_id,
name
FROM pivoted
UNPIVOT (
name FOR rnk IN ([1], [2], [3])
) u
)
SELECT *
FROM unpivoted
;
A SQL Fiddle demo to play with: http://sqlfiddle.com/#!3/354df/39.
Note that the UNPIVOT step in the above query has to be done in a separate SELECT from the PIVOT action. That is because UNPIVOT does not generate rows where columns listed in the IN column list contain NULLs. However, you could replace UNPIVOT with an equivalent technique (like CROSS APPLY) and thus move the unpivoting to the same subquery that does the pivoting:
WITH ranked AS (
SELECT
store_id,
name,
rnk = ROW_NUMBER() OVER (PARTITION BY store_id ORDER BY 1/0)
FROM stores
),
padded AS (
SELECT
store_id,
name
FROM ranked
PIVOT (
MAX(name) FOR rnk IN ([1], [2], [3])
) p
CROSS APPLY (
VALUES
(ISNULL([1], '')),
(ISNULL([2], '')),
(ISNULL([3], ''))
) x (name)
)
SELECT *
FROM padded
;
A SQL Fiddle demo for the modified version: http://sqlfiddle.com/#!3/354df/40.

Horizontal Grand Total in Pivot Table SQL

I have this query working:
select cap_idPlanoContasFin , [3684],[2234],[2] ,
from
(
select cap_idPlanoContasFin,cap_idempresa,sum(cap_valorfatura)
as Stotal
from erp_ContasPagar
group by cap_idPlanoContasFin , cap_idEmpresa
) as sourcetable
pivot
(sum(Stotal)for cap_idEmpresa in ([3684],[2234],[2])
)as pivottable;
This query returns:
cap_idPlanoContasFin 3684 2234 2
3 9000 NULL NULL
10 1057840,68 NULL 1865081,35
11 NULL 7283,1 591,9
12 NULL NULL 178914,45
13 9305,07 1117,6 500
14 NULL 59333,5 34611,74
I want to put in the same query the Horizontal Total
Example:
cap_idPlanoContasFin 3684 2234 2 Total
---------------------------------------------------------------------
13 9305,07 1117,6 500 10922,67
How to make this? I have read something with UNION.
First of all, you don't need to group your data beforehand: the PIVOT clause will do that for you. So you can remove the GROUP BY clause and change the SUM()'s argument in PIVOT accordingly:
select cap_idPlanoContasFin, [3684], [2234], [2]
from
(
select cap_idPlanoContasFin, cap_idempresa, cap_valorfatura
from erp_ContasPagar
group by cap_idPlanoContasFin , cap_idEmpresa
) as sourcetable
pivot
(
sum(cap_valorfatura) for cap_idEmpresa in ([3684], [2234], [2])
) as pivottable;
To add a total column, you could use a window SUM() like this:
select cap_idPlanoContasFin, [3684], [2234], [2], Total
from
(
select cap_idPlanoContasFin, cap_idempresa, cap_valorfatura,
sum(cap_valorfatura) over (partition by cap_idPlanoContasFin) as Total
from erp_ContasPagar
) as sourcetable
pivot
(
sum(cap_valorfatura) for cap_idEmpresa in ([3684], [2234], [2])
) as pivottable;
Note, however, that if your sourcetable includes rows with cap_idEmpresa values other than those listed in the PIVOT clause, the corresponding cap_valorfatura values will be added up too. So you might want to filter the sourcetable row set before pivoting, like this:
select cap_idPlanoContasFin, [3684], [2234], [2], Total
from
(
select cap_idPlanoContasFin, cap_idempresa, cap_valorfatura,
sum(cap_valorfatura) over (partition by cap_idPlanoContasFin) as Total
from erp_ContasPagar
where cap_idempresa in (3684, 2234, 2)
) as sourcetable
pivot
(
sum(cap_valorfatura) for cap_idEmpresa in ([3684], [2234], [2])
) as pivottable;
Thanks to all , this is the final query :
select cap_idPlanoContasFin, plc_classificador, plc_nomeConta,[3684], [2234], [2],
isnull ([2234],0) + isnull ([2],0) AS Subtotal ,Total
from
(
select A.cap_idempresa, A.cap_idPlanoContasFin, A.cap_valorfatura,
B.plc_classificador , B.plc_nomeConta,
sum(A.cap_valorfatura) over (partition by A.cap_idPlanoContasFin) as Total
from erp_ContasPagar A /*where cap_idempresa in (3684, 2234, 2)*/
inner join tbl_PlanoFinanceiro B on A.cap_idPlanoContasFin = B.plc_id
) as sourcetable
pivot
(
sum(cap_valorfatura) for cap_idEmpresa in ([3684], [2234], [2])
) as pivottable;
I need use isnull to change NULL by o to sume subtotal . Thanks again by the help