I have a query returning the results I have but I am not sure how to approach changing it to a convetion that my program uses to send data:
SELECT
[contract_member_brg_attr].attr_val AS 'field_properties',
[contract_attr].attr_val AS 'contract_number',
[other_contract_attr].attr_val AS 'supplier_number',
[MFR].ITEM_NAME AS 'supplier_name'
FROM [contract_member_brg_attr]
INNER JOIN [contract_member_brg]
ON [contract_member_brg_attr].item_id =
[contract_member_brg].item_id
INNER JOIN [contract_attr]
ON [contract_attr].item_id =
[contract_member_brg].[contract_item_id]
AND [contract_attr].field_id = 413
INNER JOIN [contract_attr] AS [other_contract_attr]
ON [other_contract_attr].item_id =
[contract_member_brg].[contract_item_id]
AND [other_contract_attr].field_id = 234
INNER JOIN [MFR] as [MFR]
ON [MFR].ITEM_PK =
[other_contract_attr].attr_val;
Results:
My issue is that I want all unique values from these results to be on 1 row. SO in this case, it would be all of the field_properties and one of each contract_number, supplier_number, supplier_name.
How would I do this what approaches are available?
EDIT:
THis is how I would want it to look:
all on one row:
column1= 388
column2 = FEB 22 2017
column3 = FEB 22 2017
column4 = test 2
column5 = test 3
column6 = true
column7 = b5v5b5b5bb5
column8 = A180
column9 = ABBOTT NUTRITION
Please look to my question about pivot. It has few successfull answers:
How to apply pivot to result of query
SELECT *
FROM (
SELECT
'id',
'field_properties',
'contract_number',
'supplier_number',
'supplier_name'
FROM (
SELECT
row_number() over (ORDER BY [contract_member_brg_attr].id) AS 'id' \\should be some analog for your DB
[contract_member_brg_attr].attr_val AS 'field_properties' ...
\\your original query
)
)
pivot (
MIN('field_properties') \\any agregation function
FOR ID IN (1, 2, 3, 4, 5, 6)
) pvt
Related
I'm trying to pull 6 records using the code below but there are some cases where the information is updated and therefore it is pulling duplicate records.
My code:
SELECT column2, count(*) as 'Count'
FROM ServiceTable p
join HIERARCHY h
on p.LOCATION_CODE = h.LOCATION
where Report_date between '2017-04-01' and '2017-04-30'
and Column1 = 'Issue '
and LOCATION = '8789'
and
( record_code = 'INCIDENT' or
(
SUBMIT_METHOD = 'Web' and
not exists
(
select *
from ServiceTable p2
where p2.record_code = 'INCIDENT'
and p2.incident_id = p.incident_id
)
)
)
The problem is that instead of the six records it is pulling eight. I would just use distinct * but the file_date is different on the duplicate entries:
FILE_DATE Incident_ID Column1 Column2
4/4/17 123 Issue Service - Red
4/4/17 123 Issue Service - Blue
4/5/17 123 Issue Service - Red
4/5/17 123 Issue Service - Blue
The desired output is:
COLUMN2 COUNT
Service - Red 1
Service - Blue 1
Any help would be greatly appreciated! If you need any other info just let me know.
If you turn your original select statement without the aggregation function into a subquery, you can distinct that on your values that are not the changing date, then select a COUNT from there. Don't forget your GROUP BY clause at the end.
SELECT Column2, COUNT(Incident_ID) AS Service_Count
FROM (SELECT DISTINCT Incident_ID, Column1, Column2
FROM ServiceTable p
JOIN HIERARCHY h ON p.LOCATION_CODE = h.LOCATION
WHERE Report_date BETWEEN '2017-04-01' AND '2017-04-30'
AND Column1 = 'Issue '
AND LOCATION = '8789'
AND
( record_code = 'INCIDENT' or
(
SUBMIT_METHOD = 'Web' and
NOT EXISTS
(
SELECT *
FROM ServiceTable p2
WHERE p2.record_code = 'INCIDENT'
AND p2.incident_id = p.incident_id)
)
)
)
GROUP BY Column2
Also, if you are joining tables it is a good practice to fully qualify the field you are selecting. Example: p.Column2, p.Incident_ID, h.LOCATION. That way, even your distinct fields are easier to follow where they came from and how they relate.
Finally, don't forget that COUNT is a reserved word. I modified your alias accordingly.
If you are using an aggregation function (count), you should use group by for the column not in the aggregation function:
SELECT column2, count(*) as 'Count'
FROM ServiceTable p
join HIERARCHY h
on p.LOCATION_CODE = h.LOCATION
where Report_date between '2017-04-01' and '2017-04-30'
and Column1 = 'Issue '
and LOCATION = '8789'
and
( record_code = 'INCIDENT' or
(
SUBMIT_METHOD = 'Web' and
not exists
(
select *
from ServiceTable p2
where p2.record_code = 'INCIDENT'
and p2.incident_id = p.incident_id
)
)
)
group by column2
I have four different select queries.
Select A,Round(B) as P,Round(C) as Q,Round(D) as R,Round(E) as S from tb_name1 a Inner Join tb_name2 b on (a.X1 =b.X2 and a.T_KEY=b.T_KEY) where a.X3="something" and a.X4="xyz" and b.X5="1243" GROUP BY A ORDER BY A DESC
Select A,Round(F) as T from tb_name4 a Join tb_name5 b on (a.K1 = b.K2 and a.K3 and b.K4 ) where a.X6="something" and a.X7="xyz1" and b.X8="1233" GROUP BY A ORDER BY A DESC
Select A,Round(G) as Q from tb_name6 a Join tb_name7 b on (a.K5 = b.K6 and a.K7 and b.K8 ) where a.X9="something" and a.X10="xyz2" and b.X11="123" GROUP BY A ORDER BY A DESC
Select A,Round(H) as R from tb_name8 a Join tb_name9 b on (a.K9 = b.K10 and a.K11 and b.K12 ) where a.X12="something" and a.X13="xyz3" and b.X14="1123" GROUP BY A ORDER BY A DESC
I have tried on Union but It's not working.I want one output using four queries and the values should be displayed as one after one values like below...
Output:--
Column's Name Column1 Column2 Column3 Column4 Column5 Column6 Column7
Row 1 valu1 valu2 valu3 valu4 valu5 valu6 valu7
Row 2 valu8 valu9 valu10 valu11 valu12 valu13 valu14
Row 3 valu15 valu16 valu17 valu18 valu19 valu20 valu21
I have a table (SQL Server 2008) with shipments, so "Stage 0" means "New shipment" and consecutive stages are diferent stages of shipment tracking.
I'm trying to pivot the following table:
CREATE TABLE TableName
([ID] int, [IDShip] int, [Date] datetime, [Stage] int, [Arg] int)
;
INSERT INTO TableName
([ID], [IDShip], [Date], [Stage], [Arg])
VALUES
(1, 1, '2013-10-03 08:36:00', 0, Null),
(2, 1, '2013-10-03 08:37:25', 1, 1),
(3, 2, '2013-10-03 08:38:25', 0, Null),
(4, 1, '2013-10-03 08:39:25', 2, 1),
(5, 2, '2013-10-03 08:40:25', 1, 3)
;
("Arg" is ID of Stage0. Select * would be:)
ID IDShip Date Stage Arg
1 1 2013-10-03 08:36:00 0 Null
2 1 2013-10-03 08:37:25 1 1
3 2 2013-10-03 08:38:25 0 Null
4 1 2013-10-03 08:39:25 2 1
5 2 2013-10-03 08:40:25 1 3
into something like:
ID0 IDShip DateShipment ID1 DateFirstStage ID2 DateSecondStage
1 1 2013-10-03 08:36:00 2 2013-10-03 08:37:25 4 2013-10-03 08:39:25
3 2 2013-10-03 08:38:25 5 2013-10-03 08:40:25
Any help? Thanks
Turned out to be a bit more messy than I hoped for but here it is:
SELECT MAX([0]) AS ID0,
IDShip,
(SELECT [Date] FROM TableName T1 WHERE T1.ID = MAX([0]) AND T1.IDShip = Y.IDShip) AS DateShipment,
MAX([1]) AS ID1,
(SELECT [Date] FROM TableName T2 WHERE T2.ID = MAX([1]) AND T2.IDShip = Y.IDShip) AS DateFirstStage,
MAX([2]) AS ID2,
(SELECT [Date] FROM TableName T3 WHERE T3.ID = MAX([2]) AND T3.IDShip = Y.IDShip) AS DateSecondStage
FROM
(SELECT * FROM TableName
PIVOT (MAX([ID]) FOR Stage IN ([0], [1], [2])) AS X) Y
GROUP BY IDShip
You first pivot the table into ID's of 3 stages and then select each stage and its date.
It appears you need to pivot more than one column at the same time. However, standard PIVOT syntax does not support multi-columnar pivoting. You could use it to pivot one of the columns, then, using those as look-up values, pull the other column values with a series of correlated subqueries.
My take on the approach was similar to #Szymon's, except I managed to avoid grouping in the outer query, although I made things more messy at other stages. Here is my attempt:
SELECT
IDShip,
ID0,
ID1,
ID2,
DateShipment = (SELECT Date FROM TableName WHERE ID = p.ID0),
DateFirstStage = (SELECT Date FROM TableName WHERE ID = p.ID1),
DateSecondStage = (SELECT Date FROM TableName WHERE ID = p.ID2)
FROM (
SELECT
ID,
IDShip,
StageID = 'ID' + CAST(Stage AS varchar(10))
FROM TableName
) AS s
PIVOT (
MAX(ID) FOR StageID IN (ID0, ID1, ID2)
) AS p
;
With proper indexing, it may not be too bad, although you could also try this alternative, which uses the older pivoting technique of grouping with conditional aggregation:
SELECT
IDShip,
ID0 = MAX(CASE Stage WHEN 0 THEN ID END),
ID1 = MAX(CASE Stage WHEN 1 THEN ID END),
ID2 = MAX(CASE Stage WHEN 2 THEN ID END),
DateShipment = MAX(CASE Stage WHEN 0 THEN Date END),
DateFirstStage = MAX(CASE Stage WHEN 1 THEN Date END),
DateSecondStage = MAX(CASE Stage WHEN 2 THEN Date END)
FROM TableName
GROUP BY IDShip
;
This SQL Fiddle demo will let you try both solutions.
I want to build columns that calculated with each other. (Excuse my English)
Example:
Id Column1 Column2 Column3
1 5 5 => Same as Column1 5 => Same as Column2
2 2 12 => column1 current + column2.prev + column3.previous = 2+5+5 17 => column2.current + column3.prev = 12+5
3 3 32 => 3+12+17 49 => 32+17
easier way to see:
Id Column1 Column2 Column3
1 5 5 => Same as Column1 5 => Same as Column2
2 2 12 => 2+5+5 17 => 12+5
3 3 32 => 3+12+17 49 => 32+17
so complicated??? :-(
The previous issue was calculating Column3 with the new calculated column as Column2. But now, it must be renew with the just calculated Column2 and the previous record of Column3 as well. If you want to have a look at the previous post, here it is.
Here is my previous recursive CTE code. It works like, 1st, calculate column2 with previous record of current column (c.Column2) in cteCalculation, and then calculate new column3 in cte2 with just calculated column2 from cteCalculation.
/copied from that previous post/
;with cteCalculation as (
select t.Id, t.Column1, t.Column1 as Column2
from table_1 t
where t.Id = 1
union all
select t.Id, t.Column1, (t.Column1 + c.Column2) as Column2
from table_1 t
inner join cteCalculation c
on t.Id-1 = c.id
),
cte2 as(
select t.Id, t.Column1 as Column3
from table_1 t
where t.Id = 1
union all
select t.Id, (select column2+1 from cteCalculation c where c.id = t.id) as Column3
from table_1 t
inner join cte2 c2
on t.Id-1 = c2.id
)
select c.Id, c.Column1, c.Column2, c2.column3
from cteCalculation c
inner join cte2 c2 on c.id = c2. id
Now I wanna extend it like calculate 2 columns with the data from each other. Means, use 2nd to calc the 3rd, and use 3rd to get new 2nd column data. Hope you can get it.
This is an example how to achive this using recursive CTE
create table #tmp (id int identity (1,1), Column1 int)
insert into #tmp values(5)
insert into #tmp values(2)
insert into #tmp values(3);
with counter as
(
SELECT top 1 id, Column1, Column1 as Column2, Column1 as Column3 from #tmp
UNION ALL
SELECT t.id, t.Column1,
t.Column1 + counter.Column2 + counter.Column3,
(t.Column1 + counter.Column2 + counter.Column3) + counter.Column3 FROM counter
INNER JOIN #tmp t ON t.id = counter.id + 1
)
select * from counter
You'll need to use a Recursive CTE since the values of subsequent columns are dependent upon earlier results.
Do this in pieces, too. Have your first query just return the correct values for Column1. Your next (recursive CTE) query will add the results for Column2, and so on.
OK I'm assuming you're doing inserts into column 1 here of various values.
Essentially col2 always = new col1 value + old col2 value + old col 3 value
col3 = new col2 value + old col3 value
so col3 = (new col1 value + old col2 value + old col 3 value) + old col3 value
So an INSTEAD OF Insert trigger is probably the easiest way to implement.
CREATE TRIGGER tr_xxxxx ON Tablename
INSTEAD OF INSERT
AS
INSERT INTO Tablename (Column1, Column2, Column3)
SELECT ins.col1, ins.col1+t.col2+t.col3, ins.col1+t.col2+t.col3+t.col3
FROM Tablename t INNER JOIN Inserted ins on t.Id = ins.Id
The trigger has access to both the existing (old) values in Tablename t, and the new value being inserted (Inserted.col1).
I have following table:
ID Data
1 A
2 A
2 B
3 A
3 B
4 C
5 D
6 A
6 B
etc. In other words, I have groups of data per ID. You will notice that the data group (A, B) occurs multiple times. I want a query that can identify the distinct data groups and number them, such as:
DataID Data
101 A
102 A
102 B
103 C
104 D
So DataID 102 would resemble data (A,B), DataID 103 would resemble data (C), etc. In order to be able to rewrite my original table in this form:
ID DataID
1 101
2 102
3 102
4 103
5 104
6 102
How can I do that?
PS. Code to generate the first table:
CREATE TABLE #t1 (id INT, data VARCHAR(10))
INSERT INTO #t1
SELECT 1, 'A'
UNION ALL SELECT 2, 'A'
UNION ALL SELECT 2, 'B'
UNION ALL SELECT 3, 'A'
UNION ALL SELECT 3, 'B'
UNION ALL SELECT 4, 'C'
UNION ALL SELECT 5, 'D'
UNION ALL SELECT 6, 'A'
UNION ALL SELECT 6, 'B'
In my opinion You have to create a custom aggregate that concatenates data (in case of strings CLR approach is recommended for perf reasons).
Then I would group by ID and select distinct from the grouping, adding a row_number()function or add a dense_rank() your choice. Anyway it should look like this
with groupings as (
select concat(data) groups
from Table1
group by ID
)
select groups, rownumber() over () from groupings
The following query using CASE will give you the result shown below.
From there on, getting the distinct datagroups and proceeding further should not really be a problem.
SELECT
id,
MAX(CASE data WHEN 'A' THEN data ELSE '' END) +
MAX(CASE data WHEN 'B' THEN data ELSE '' END) +
MAX(CASE data WHEN 'C' THEN data ELSE '' END) +
MAX(CASE data WHEN 'D' THEN data ELSE '' END) AS DataGroups
FROM t1
GROUP BY id
ID DataGroups
1 A
2 AB
3 AB
4 C
5 D
6 AB
However, this kind of logic will only work in case you the "Data" values are both fixed and known before hand.
In your case, you do say that is the case. However, considering that you also say that they are 1000 of them, this will be frankly, a ridiculous looking query for sure :-)
LuckyLuke's suggestion above would, frankly, be the more generic way and probably saner way to go about implementing the solution though in your case.
From your sample data (having added the missing 2,'A' tuple, the following gives the renumbered (and uniqueified) data:
with NonDups as (
select t1.id
from #t1 t1 left join #t1 t2
on t1.id > t2.id and t1.data = t2.data
group by t1.id
having COUNT(t1.data) > COUNT(t2.data)
), DataAddedBack as (
select ID,data
from #t1 where id in (select id from NonDups)
), Renumbered as (
select DENSE_RANK() OVER (ORDER BY id) as ID,Data from DataAddedBack
)
select * from Renumbered
Giving:
1 A
2 A
2 B
3 C
4 D
I think then, it's a matter of relational division to match up rows from this output with the rows in the original table.
Just to share my own dirty solution that I'm using for the moment:
SELECT DISTINCT t1.id, D.data
FROM #t1 t1
CROSS APPLY (
SELECT CAST(Data AS VARCHAR) + ','
FROM #t1 t2
WHERE t2.id = t1.id
ORDER BY Data ASC
FOR XML PATH('') )
D ( Data )
And then going analog to LuckyLuke's solution.