retrieve data based on derived column - sql-server

How to rewrite the below code as working sql. I need to retrieve 'item' from another table based on my new 'newcol'
The code is.
select
s.code,
o.[work name],
case when o.[work name] is null
then s.code
else o.[work name]
end newcol,
item=(select item from table1 where table1.code=newcol)
from
shoplog s
left outer join odc o on o.barcode=s.code

You can use sub-query to achieve what you need.
select a.code, a.[work name], a.newcol, b.code as item
from
(select
s.code,
o.[work name],
case when o.[work name] is null
then s.code
else o.[work name]
end newcol
from
#shoplog s
left outer join #odc o on o.barcode=s.code
)a
inner join
#table1 b
on (a.newcol = b.code)

Related

Join INFORMATION_SCHEMA.TABLES with another table with more TABLE_NAMES and result would be different if table name is in the first table or not

we have a Table with a list of table names we want to be created. They don't have an ID column or anything, it's just a few rows of data with 2 columns. Thing is we want to merge that table with Information_schema.table to check which of the tables we have already created and which we have not, so we wrote the query below as a temp to achieve such:
with cte1 as (
select d.TABNAME, d.CLASS from dbo.table_list as d
left join INFORMATION_SCHEMA.TABLES as t on t.TABLE_NAME = d.TABNAME
where d.CLASS in ('INIT','STERN') and table_schema = 'dbo'),
cte2 as (select d.TABNAME, d.CLASS
from dbo.table_list as d
where d.CLASS in ('INIT','TERN') and d.TABNAME not in (select [TABLE NAME] from cte1))
select *, 'Active' as [Status] from cte1 union all
select * , 'Inactive' from cte2
This is what table_list looks like:
TABNAME
CLASS
TABLE1
INIT
TABLE2
STERN
TABLE3
STERN
TABLE4
STERN
TABLE5
INIT
We already have TABLE1 and TABLE2 created so the result of the query looks like this:
TABNAME
CLASS
STATUS
TABLE1
INIT
Active
TABLE2
STERN
Active
TABLE3
STERN
Inactive
TABLE4
STERN
Inactive
TABLE5
INIT
Inactive
It works well enough like this but we were wondering if we could make it shorter.
This can be way shorter, yes. You could just reference the table dbo.table_list and see if you get a valid OBJECT_ID:
SELECT tl.TABNAME,
tl.CLASS,
CASE WHEN OBJECT_ID(N'dbo.' + QUOTENAME(tl.TABNAME)) IS NULL THEN 'Inactive' ELSE 'Active' END AS Status
FROM dbo.table_list tl --"d" for "table_list" doesn't make a lot of sense.
WHERE tl.CLASS IN ('INIT','STERN');
If you wanted to use the catalog views, you could use CROSS APPLY to join to the table while supplying a value for both the schema and table name, or just JOIN to sys.schemas based on a literal and then LEFT JOIN to sys.tables:
SELECT tl.TABNAME,
tl.CLASS,
CASE WHEN st.[name] IS NULL THEN 'Inactive' ELSE 'Active' END AS Status
FROM dbo.table_list tl --"d" for "table_list" doesn't make a lot of sense.
CROSS APPLY (SELECT t.[name]
FROM sys.schemas s
JOIN sys.tables t ON s.schema_id = t.schema_id
WHERE s.[name] = N'dbo'
AND t.[name] = tl.TABNAME) st
WHERE tl.CLASS IN ('INIT','STERN');
SELECT tl.TABNAME,
tl.CLASS,
CASE WHEN t.[name] IS NULL THEN 'Inactive' ELSE 'Active' END AS Status
FROM dbo.table_list tl --"d" for "table_list" doesn't make a lot of sense.
JOIN sys.schemas s ON s.[name] = N'dbo'
LEFT JOIN sys.tables t ON s.schema_id = t.schema_id
AND tl.TABNAME = t.[name]
WHERE tl.CLASS IN ('INIT','STERN');

subquery does not work correctly

i have used below sub-query for returning maximum data of each (Document Number) from my query but it returns just one record while i have many records.
SELECT tblTransmittals.[Owner Document Number]
, tblTransmittals.[Int-Tr- NO]
, tbltransmittalNo.[Internal-Tr-Date]
FROM tblTransmittals
INNER JOIN tbltransmittalNo
ON tblTransmittals.[Int-Tr- NO] = tbltransmittalNo.[Int-Tr-NO]
WHERE (((tbltransmittalNo.[Internal-Tr-Date])=
(SELECT Max(A.[Internal-Tr- Date])
FROM (SELECT tblTransmittals.[Owner Document Number]
, tbltransmittalNo. [Internal-Tr-Date]
FROM tblTransmittals
INNER JOIN tbltransmittalNo
ON tblTransmittals.[Int-Tr-NO] = tbltransmittalNo.[Int-Tr-NO]
) AS A
WHERE A.[owner Document Number]=[tblTransmittals].[Owner Document Number])));
i mean if data of query is like below :
Owner Document Number Int-Tr-NO Internal-Tr-Date
doc-0001 tt-0002 10-oct-2016
doc-0001 tt-0003 12-0ct-2017
doc-0005 tt-0100 18-sep-2015
i would like after using subquery it returns:
Owner Document Number Int-Tr-NO Internal-Tr-Date
doc-0001 tt-0003 12-0ct-2017
doc-0005 tt-0100 18-sep-2015
i tried and checked everything but i do not know why does not work?
Not totally clear what you want here and I am assuming this is sql server. Think you want something like this.
select *
from
(
SELECT t.[Owner Document Number]
, t.[Int-Tr- NO]
, tn.[Internal-Tr-Date]
, RowNum = ROW_NUMBER() over (partition by t.[Owner Document Number] order by tbltransmittalNo.[Internal-Tr-Date] desc)
FROM tblTransmittals t
INNER JOIN tbltransmittalNo tn ON t.[Int-Tr- NO] = tn.[Int-Tr-NO]
) x
where x.RowNum = 1
SELECT tblTransmittals.[Owner Document Number], tblTransmittals.[Int-Tr-NO], tbltransmittalNo.[Internal-Tr-Date]
FROM tblTransmittals INNER JOIN tbltransmittalNo ON tblTransmittals.[Int-Tr-NO] = tbltransmittalNo.[Int-Tr-NO]
WHERE (((tbltransmittalNo.[Internal-Tr-Date])=
(SELECT Max([Internal-Tr-Date])
FROM (SELECT T.[Owner Document Number], T.[Int-Tr-NO], TN.[Internal-Tr-Date]
FROM tblTransmittals AS T LEFT JOIN tbltransmittalNo AS TN ON T.[Int-Tr-NO] = TN.[Int-Tr-NO]) AS A
WHERE A.[owner Document Number]=[tblTransmittals].[Owner Document Number])));
Your query is totally incorrect as it only returns one row due to the max() on your sub-query:
(SELECT Max(A.[Internal-Tr- Date])
FROM (SELECT tblTransmittals.[Owner Document Number], tbltransmittalNo. [Internal-Tr-Date]
FROM tblTransmittals INNER JOIN tbltransmittalNo
ON tblTransmittals.[Int-Tr-NO] = tbltransmittalNo.[Int-Tr-NO]) AS A
WHERE A.[owner Document Number]=[tblTransmittals].[Owner Document Number]);
##this query only returns 1 value
In your scenario above, the max() query will return "12-0ct-2017" and your final query will look like this:
SELECT tblTransmittals.[Owner Document Number], tblTransmittals.[Int-Tr- NO], tbltransmittalNo.[Internal-Tr-Date]
FROM tblTransmittals INNER JOIN tbltransmittalNo
ON tblTransmittals.[Int-Tr- NO] = tbltransmittalNo.[Int-Tr-NO]
WHERE (((tbltransmittalNo.[Internal-Tr-Date])= '20171012'
I'm guessing that you want to return max(date) on each of the [Owner Document Number] and so I would do this:
SELECT A.[Owner Document Number], A.[Int-Tr- NO], B.[Internal-Tr-Date]
FROM tblTransmittals as A INNER JOIN tbltransmittalNo as B
ON A.[Int-Tr- NO] = B.[Int-Tr-NO]
JOIN
(SELECT C.[Owner Document Number], max(D.[Internal-Tr-Date])
FROM tblTransmittals as C INNER JOIN tbltransmittalNo as D
ON C.[Int-Tr-NO] = D.[Int-Tr-NO] GROUP BY C.[Owner Document Number]) AS E
ON A.[Owner Document Number] = E.[Owner Document Number]
and B.[Internal-Tr-Date] = E.[Internal-Tr-Date]
Good luck.

Multiple aggregate functions in SQL Server

I need a query for [Contribution]. I used this query:
with ttt as
(
select
(DYG.U_StyleId)[DYG Style]
,Max(O1.CardCode) [Party Group Code],
MAX(O1.CardName) [Party Group Name]
,MAX(OR1.DocDate) [Date]
,sum(CONVERT(NUMERIC(15,2),(RDR1.PriceBefDi*RDR1.Quantity))) [JobAmount]
,CONVERT(NUMERIC(15,2),SUM(RDR1.Quantity)) [Mtr]
,CONVERT(NUMERIC(15,2),SUM(RDR1.U_Pcs))[Pcs]
,(select sum(RDR1.PriceBefDi*RDR1.Quantity) from RDR1) tqty
from
ORDR OR1
left join RDR1 on RDR1.DocEntry = OR1.DocEntry
left join OITM on RDR1.ItemCode = oitm.ItemCode
LEFT JOIN OCRD ON OCRD.CardCode = OR1.CardCode
LEFT JOIN OCRG ON OCRG.GroupCode = OCRD.GroupCode
LEFT JOIN OCRD O1 ON O1.U_BCode = OCRD.U_GrpCod
LEFT JOIN
( SELECT U_StyleId FROM RDR1 WHERE U_StyleId in
('BLOOM','BLOOMING','DYD','DYD-R','DYED','Ex.CLR.','RAINBOW'))
DYG ON DYG.U_StyleId = RDR1.U_StyleId
group by
DYG.U_StyleId
)
select
Style, [Party Group Code],
[Party Group Name], JobAmount,
(sum(JobAmount) / tqty * 100) [Contribution],
[Date], [Pcs]
from
ttt
group by
Style
I need Sum of last jobamount to divide it with above tqty.
But it shows this error.
'Column 'ttt.Party Group Code' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.'
Please help me with the query to get right [Contribution] amount.
Try this:
select Style,[Party Group Code],[Party Group Name],JobAmount,[Date],[Pcs],
100.0 * (sum(JobAmount) OVER (PARTITION BY Style))/tqty [Contribution]
from ttt;

inner join on different qaunties

i have two Identical tables in my SQL database these tables consist of Item Code and QTY each.
I need to see which items in both tables that have different quantities AND the items that
don't exist in the other table
I tried using FULL OUTER JOIN ON ITEMCODE=ITEMCODE AND QTY<>QTY
IT IS NOT WORKING
the result i am getting is something like that:
http://www.sendspace.com/file/nmb7yu
Try something like this:
SELECT c.Code ,
t1.Code ,
t1.Qty ,
t2.Code ,
t2.Qty
FROM ( SELECT Code
FROM dbo.Table1
UNION
SELECT Code
FROM dbo.Table2
) c
LEFT OUTER JOIN dbo.Table1 t1 ON c.Code = t1.Code
LEFT OUTER JOIN dbo.Table2 t2 ON c.Code = t2.Code
WHERE t1.Code IS NULL
OR t2.Code IS NULL
OR t1.Qty <> t2.Qty
Since you have a test for inequality in the WHERE clause you're implicitly only including items that are in both tables. This way you include items that are in one table, but not the other, or have the difference in quantity.
select *
from table1 a full outer join table2 b
on a.code = b.code
where a.qty <> b.qty or a.code is null or b.code is null
my lucky guess is that you filtered out rows where code column is null

Place Data from Same Column in Different Columns in Resultset

I have a request I wasn't sure to handle. I was thinking of using PIVOT, but I wasn't sure if that would be the way to go.
I have the following Data:
EmployeeA, DepartmentB, 1/10/2010
EmployeeA, DepartmentA, 1/1/2000
EmployeeB, DepartmentC, 1/3/2011
They want output for only the employees that have been in different departments. Something that looks like this (order is important due to the dates):
EmployeeA, DepartmentA, DepartmentB
Any help is appreciated. For some reason, my mind isn't finding a good solution.
You can do this by doing a self JOIN on the table and then using a PIVOT to get the data in the format that you want:
SELECT *
FROM
(
SELECT t1.emp, t1.dept, t1.dt
FROM test t1
INNER JOIN test t2
ON t1.emp = t2.emp
AND t1.dept != t2.dept
) x
PIVOT
(
min(dt)
for dept in ([A], [B], [C], [D], [E])
) p
See SQL Fiddle with Demo
If you remove the JOIN you will get all records, but you stated you only want the records that have been in more than one department.
Here's the answer I got which I got largely based on your work. Pivot doesn't work because I don't know the categories (in this case Department) ahead of time and I can only have two of them.
Maybe there's an easier way. I didn't use a CTE, because I believe this should work for Sybase as well which I don't think supports that.
select Meta1.[Employee ID],
Meta1.Department as PreviousDepartment,
Meta2.Department as CurrentDepartment
from
(
SELECT t1.[First Name], t1.[Last Name],
t1.[Employee ID], t1.Department, t1.[Hire Date],
ROW_NUMBER() over(PARTITION by t1.[EMPLOYEE ID] order by t1.[Hire Date]) as RowNum
FROM EMPLOYEE t1
INNER JOIN EMPLOYEE t2
ON t1.[Employee ID] = t2.[Employee ID]
AND t1.Department != t2.Department
) Meta1
inner join
(
SELECT t1.[Employee ID], t1.Department, t1.[Hire Date],
ROW_NUMBER() over(PARTITION by t1.[EMPLOYEE ID] order by t1.[Hire Date]) as RowNum
FROM EMPLOYEE t1
INNER JOIN EMPLOYEE t2
ON t1.[Employee ID] = t2.[Employee ID]
AND t1.Department != t2.Department
) Meta2
on Meta1.[Employee ID]=Meta2.[Employee ID]
where Meta1.RowNum=1
and Meta2.RowNum=2

Resources