SQL Group Results and Add them up based on product - sql

I've got the following SQL which basically works out the costings etc for each item.
SELECT
L.LocID,
L.LocationName,
L.LocationSqrMtr,
L.LocationAddress,
L.LocationPostCode,
L.LocationContact,
I.SubPIDItemID,
I.SPID,
I.ProductID,
C.SubPIDCostID,
C.PricePerItem,
C.ManDayPerItem
FROM
dbo.SubPIDCosts AS C
INNER JOIN dbo.SubPIDItems AS I ON
C.ProductID = I.ProductID
RIGHT OUTER JOIN dbo.SubPIDLocations AS L ON
I.LocationID = L.LocID AND C.LocationID = L.LocID
WHERE C.SPID = 48
This returns:
+-------+--------------+----------------+-----------------+------------------+-----------------+--------------+----------+-----------+--------------+--------------+---------------+-----+----+---+-----+--------+--------+--------+------+
| LocID | LocationName | LocationSqrMtr | LocationAddress | LocationPostCode | LocationContact | SubPIDItemID | SPID | ProductID | SubPIDCostID | PricePerItem | ManDayPerItem | | | | | | | | |
+-------+--------------+----------------+-----------------+------------------+-----------------+--------------+----------+-----------+--------------+--------------+---------------+-----+----+---+-----+--------+--------+--------+------+
| 379 | | | Location | 1 | 1 | 345 | Generic | Building | Generic | Building | NULL | 158 | 48 | | | | 108 | 0.3400 | 6.17 |
| 379 | | | Location | 1 | 1 | 345 | Generic | Building | Generic | Building | NULL | 159 | 48 | 1 | 109 | 0.3400 | | .47 | |
| 379 | 3 | Location | 1 | 615 | Generic | Building | Generic | Building | NULL | 160 | 48 | | | | 110 | 0.7317 | 0.50 | | |
| 379 | 4 | Location | | | 615 | Generic | Building | Generic | Building | NULL | 161 | 48 | | | | 111 | 0.7317 | 0.50 | |
| 379 | 4 | Location | | | 615 | Generic | Building | Generic | Building | NULL | 16 | | 48 | 1 | 11 | | 0.7317 | 0.50 | |
+-------+--------------+----------------+-----------------+------------------+-----------------+--------------+----------+-----------+--------------+--------------+---------------+-----+----+---+-----+--------+--------+--------+------+
But what I would like to do is group it by the product ID. So all the ones that are ProductID 22 it should add the values up for ManDayPerItem and PricePerItem and LocationSqrMtr
It's used in the following context
I'd like to have them grouped nicely in that list.

As you said, group by:
SELECT ProductID, SUM(ManDayPerItem), SUM(PricePerItem), SUM(LocationSqrMtr)
FROM
dbo.SubPIDCosts AS C
INNER JOIN dbo.SubPIDItems AS I ON
C.ProductID = I.ProductID
RIGHT OUTER JOIN dbo.SubPIDLocations AS L ON
I.LocationID = L.LocID AND C.LocationID = L.LocID
WHERE C.SPID = 48
GROUP BY ProductID;

Related

SQL Merge two Tables

Let's say I have these 2 tables:
ArticleTBL
+---------+----------+-------------+------------+
|articleid| typeid | price | user |
+---------+----------+-------------+------------+
| 0 | 2 | 1 | 122 |
| 1 | 3 | 2 | 344 |
| 2 | 3 | 1 | 455 |
| 3 | 1 | 4 | 34 |
+---------+----------+-------------+------------+
TypeTBL
+---------+----------+-------------+
|typeid | type | factory |
+---------+----------+-------------+
| 0 | wooden | factry1 |
| 1 | plastic | factry2 |
| 2 | metal | factry3 |
| 3 | sth. | factry4 |
+---------+----------+-------------+
How do I request all this information only with articleid for each row?
Isn't this what you want? Read more
SELECT a.articleid,
a.price.a.USER,
t.typeid,
t.type,
t.factory
FROM form ArticleTBL a
INNER JOIN typetbl t
ON a.typeid = t.typeid
WHERE a.articleid = 0

Selecting the first instance of a vendor, part combination

I am trying to create an indicator for if a particular transaction was the first time a part was purchased from a particular vendor.
I have a dataset that looks like this:
| transaction_id | vendor_id | part_id | trans_date |
|:--------------:|:---------:|:-------:|:-----------------:|
| 9Bx*2Pc' | a | 873 | 10/12/2018 |
| 1Po.4Ot, | a | 473 | 4/22/2016 |
| 9Sk"7Kv/ | b | 123 | 7/23/2016 |
| 2Lz&7Hu& | a | 873 | 12/20/2017 |
| 8Lz)5Is# | b | 743 | 10/22/2016 |
| 5Sc'6Jl/ | a | 113 | 10/6/2016 |
| 0Ra&8Hb& | a | 653 | 10/4/2017 |
| 4Wc-8Of* | c | 333 | 8/3/2017 |
| 8Vv+9Yo/ | c | 333 | 12/7/2016 |
| 6Qh!1Ha- | c | 333 | 3/28/2017 |
| 2Ol%4Rs# | c | 333 | 5/2/2017 |
| 1Gg#8Cm% | c | 333 | 11/15/2016 |
| 0Lw(6Pv/ | d | 873 | 8/13/2017 |
| 1Gy/7Zw, | a | 443 | 10/12/2018 |
| 2Gz,4Gp. | b | 103 | 1/5/2018 |
| 5Dj)6Wc+ | a | 893 | 12/17/2016 |
| 5Hl-8Ds! | a | 903 | 12/8/2017 |
| 8Ws$3Vy* | b | 873 | 1/13/2018 |
What I am looking to do is determine if the transaction_id was the first time (sorted by trans_date), that the part_id was purchased from a vendor_id. I would imagine the ideal output to look like this:
| transaction_id | vendor_id | part_id | trans_date | first_time |
|:--------------:|:---------:|:-------:|:-----------------:|:----------:|
| 9Bx*2Pc' | a | 873 | 10/12/2018 | N |
| 1Po.4Ot, | a | 473 | 4/22/2016 | Y |
| 9Sk"7Kv/ | b | 123 | 7/23/2016 | Y |
| 2Lz&7Hu& | a | 873 | 12/20/2017 | Y |
| 8Lz)5Is# | b | 743 | 10/22/2016 | Y |
| 5Sc'6Jl/ | a | 113 | 10/6/2016 | Y |
| 0Ra&8Hb& | a | 653 | 10/4/2017 | Y |
| 4Wc-8Of* | c | 333 | 8/3/2017 | N |
| 8Vv+9Yo/ | c | 333 | 12/7/2016 | N |
| 6Qh!1Ha- | c | 333 | 3/28/2017 | N |
| 2Ol%4Rs# | c | 333 | 5/2/2017 | N |
| 1Gg#8Cm% | c | 333 | 11/15/2016 | Y |
| 0Lw(6Pv/ | d | 873 | 8/13/2017 | Y |
| 1Gy/7Zw, | a | 443 | 10/12/2018 | Y |
| 2Gz,4Gp. | b | 103 | 1/5/2018 | Y |
| 5Dj)6Wc+ | a | 893 | 12/17/2016 | Y |
| 5Hl-8Ds! | a | 903 | 12/8/2017 | Y |
| 8Ws$3Vy* | b | 873 | 1/13/2018 | Y |
So far, I have tried (which was influenced by this post):
WITH
first_instance AS (
SELECT
tbl_trans.*,
ROW_NUMBER() OVER (PARTITION BY vendor_id||part_id ORDER BY trans_date) AS row_nums
FROM
tbl_trans
)
SELECT
x.*,
CASE WHEN y.row_nums = 1 THEN 'Y' ELSE 'N' END AS first_time_indicator
FROM
tbl_trans x
LEFT JOIN first_instance y
But I am met with:
ORA-00905: missing keyword
I have created a SQL FIDDLE with this data and the query thus far for testing. How can I determine the if a transaction was a first time purchase for a part/vendor combination?
Use window functions:
select t.*,
(case when row_number() over (partition by vendor_id, part_id order by trans_date) = 1
then 'Y' else 'N'
end) as first_time
from tbl_trans t;
You don't need a join.
Apart from row_number, there are multiple ways of achieving the desired result using analytical function as follows.
You can use first_value analytical function as follows:
Select t.*,
Case
when first_value(trans_date)
over (partition by vendor_id, part_id order by trans_date) = trans_date
then 'Y'
else 'N'
end as first_time
From your_table t;
The same way, you can also use min as follows:
Select t.*,
Case
when min(trans_date)
over (partition by vendor_id, part_id) = trans_date
then 'Y'
else 'N'
end as first_time
From your_table t;

SQL subcategory total is not properly placed at the end of every parent category

I am having trouble in SQl query,The query result should be like this
+------------+------------+-----+------+-------+--+--+--+
| District | Tehsil | yes | no | Total | | | |
+------------+------------+-----+------+-------+--+--+--+
| ABBOTTABAD | ABBOTTABAD | 377 | 5927 | 6304 | | | |
| ABBOTTABAD | HAVELIAN | 112 | 2276 | 2388 | | | |
| ABBOTTABAD | Overall | 489 | 8203 | 8692 | | | |
| CHARSADDA | CHARSADDA | 289 | 3762 | 4051 | | | |
| CHARSADDA | SHABQADAR | 121 | 1376 | 1497 | | | |
| CHARSADDA | TANGI | 94 | 1703 | 1797 | | | |
| CHARSADDA | Overall | 504 | 6841 | 7345 | | | |
+------------+------------+-----+------+-------+--+--+--+
The overall total should be should be shown at the end of every parent category but now it is showing like this
+------------+------------+-----+------+-------+--+--+--+
| District | Tehsil | yes | no | Total | | | |
+------------+------------+-----+------+-------+--+--+--+
| ABBOTTABAD | ABBOTTABAD | 377 | 5927 | 6304 | | | |
| ABBOTTABAD | HAVELIAN | 112 | 2276 | 2388 | | | |
| ABBOTTABAD | Overall | 489 | 8203 | 8692 | | | |
| CHARSADDA | CHARSADDA | 289 | 3762 | 4051 | | | |
| CHARSADDA | Overall | 504 | 6841 | 7345 | | | |
| CHARSADDA | SHABQADAR | 121 | 1376 | 1497 | | | |
| CHARSADDA | TANGI | 94 | 1703 | 1797 | | | |
+------------+------------+-----+------+-------+--+--+--+
My query is sorting second column with respect to first column although order by query is applied on my first column. This is my query
select District as 'District', tName as 'tehsil',[1] as 'yes',[0] as 'no',ISNULL([1]+[0], 0) as "Total" from
(
select d.Name as 'District',
case when grouping (t.Name)=1 then 'Overall' else t.Name end as tName,
BoundaryWallAvailable,
count(*) as total from School s
INNER JOIN SchoolIndicator i ON (i.refSchoolID=s.SchoolID)
INNER JOIN Tehsil t ON (t.TehsilID=s.refTehsilID)
INNER JOIN district d ON (d.DistrictID=t.refDistrictID)
group by
GROUPING sets((d.Name, BoundaryWallAvailable), (d.Name,t.Name, BoundaryWallAvailable))
) B
PIVOT
(
max(total) for BoundaryWallAvailable in ([1],[0])
) as Pvt
order by District
P.S: BoundaryWall is one column through pivoting i am breaking it into Yes and No Column

Transpose data using sql oracle

I have following data in a table
+---------+-----+----------+
| Zip_ cd | id | assignmt.|
|---------+-----+----------+
| 1812 | 777 | S |
| 1812 | 111 | P |
| 1451 | 878 | S |
| 55 | 45 | x |
| 55 | 646 | T |
| 55 | 455 | Z |
+---------+-----+----------+
I want to transpose it as following
+---------+-----+----+---------+-----+----------+---------+-----+----------+
| Zip_ cd | id | ass| Zip_cd1 | id1 |assignmt1 | Zip_cd2 | id2 |assignmt3 |
+---------+-----+----+---------+-----+----------+---------+-----+----------+
| 1812 | 777 | S | 1812 | 111 | P | 1812 | 111 | P |
| 1451 | 878 | S | | | | | | |
| 55 | 45 | X | 55 | 646 | T | 55 | 455 | Z |
+---------+-----+----------+---------+----------+---------+-----+----------+
So, I basically want to transpose based on the zip code. If 2 rows have same zip code its needs to be in single row.
Another query using pivot functionality:
select *
from table_name
pivot ( max(id) id
, max(assignmt) assignmt
FOR assignmt IN ('S' S,
'P' P));
+---------+-------+------------+--------+------------+
| ZIP_ CD | S_ID | S_ASSIGNMT.| P_ID | P_ASSIGNMT.|
+---------+-------+------------+--------+------------+
| 1812 | 777 | S | 111 | P |
| 1451 | 878 | S | NULL | NULL |
+---------+-------+------------+--------+------------+

rolling up data and getting SUM group by

I have two tables:
**OrgPhysicianMappingtbl**
org varchar
physician varchar
**PhysicianDatatbl**
physician varchar
names varchar
datapoint int
data from OrgPhysicianMappingtbl:
+---------+-----------+
| org | physician |
+---------+-----------+
| ABC123 | B032 |
| ABC123 | B023 |
| ABC123 | A022 |
| ABB443 | A32 |
| ABB332 | F23 |
| BVD222 | G23 |
| BVD222 | GG2 |
| BOS5223 | G4 |
+---------+-----------+
data from PhysicianDatatbl:
+------------+----------------------------------+-----------+
| physician | names | datapoint |
+------------+----------------------------------+-----------+
| B032 | CASH | 68 |
| B032 | MEDICAID | 89 |
| B032 | ALL THIRD PARTY | 3,769 |
| B032 | WORKERS COMP | 39 |
| B032 | US SCRIPT (PROC-UNSP) | 86 |
| B032 | MEDCO HLTH SOLUTIONS (PROC-UNSP) | 79 |
| B032 | BCBS WELLPOINT/ANTHEM/WEL UNSPEC | 76 |
| B032 | KY EMPLOYEES HLTH PLN/KEHP (KY) | 62 |
| B032 | UHC/PAC/AARP MED PDP GENERAL(KY) | 52 |
| B032 | WELLCARE OF KENTUCKY (KY) | 42 |
| B032 | CCRX MED PDP GENERAL (KY) | 39 |
| B032 | WORKERS COMP - EMPLOYER | 37 |
| B032 | HUMANA/CAREPLS MED D GENERAL(KY) | 27 |
| B032 | CIGNA MEDICARE RX PDP GNRL (KY) | 26 |
| B023 | CASH | 167 |
| B023 | MEDICAID | 34 |
| B023 | ALL THIRD PARTY | 3,165 |
| B023 | WORKERS COMP | 56 |
| B023 | WORKERS COMP - EMPLOYER | 50 |
| B023 | BLUE CHOICE PPO (TX) | 48 |
| B023 | TRICARE HUMANA MILITARY SOUTH | 47 |
| B023 | MEDCO HLTH SOLUTIONS (PROC-UNSP) | 32 |
| B023 | BROADSPIRE INC | 27 |
| B023 | ADVANCEPCS (PROC-UNSP) | 27 |
| B023 | UNITED HLTHCARE-(TX) TEXAS | 23 |
| B023 | HEALTHSPRING PDP (TX) | 18 |
| B023 | AETNA INC.-(TX) HOUSTON | 13 |
| B023 | WELLCARE MEDICARE D GENERAL(TX) | 12 |
+------------+----------------------------------+-----------+
example of desired result:
+-----------+-----------------+-----------+
| org | names | sum(datapoints|
+-----------+-----------------+-----------+
| ABC123 | CASH | 236 |
| ABC123 | MEDICAID | 123 |
| ABC123 | ALL THIRD PARTY | 6,933 |
| ABC123 | WORKERS COMP | 94 |
| … | … | … |
+-----------+-----------------+-----------+
I need to roll up my data to the ORG level. There are multiple physicians per ORG. every physician has names and datapoints associated with it. The result that I want is the sum of all datapoints per names rolled up to the org level.
Can someone please get me started on this?
here's what i tried:
select o.org,p.names,sum(p.datapoint)
from OrgPhysicianMappingtbl o
join PhysicianDatatbl p
on o.physician=p.physician
group by o.org,p.names
You can use GROUPING SETS:
select o.org, p.names, sum(p.datapoint)
from OrgPhysicianMappingtbl o
inner join PhysicianDatatbl p
on o.physician = p.physician
GROUP BY GROUPING SETS((o.org), (p.names))
see SQL Fiddle with Demo
Well!
SELECT o.org, p.names, sum(p.datapoint)
FROM OrgPhysicianMappingtbl o INNER JOIN PhysicianDatatbl p
ON o.physician = p.physician
GROUP BY o.org, p.names
http://www.sqlfiddle.com/#!2/f59c4/1
select o.org,p.names,sum(p.datapoint)
from OrgPhysicianMappingtbl o
join PhysicianDatatbl p
on o.physician=p.physician
group by o.org,p.names with ROLLUP
Even this should work
SELECT org,names,TotalDP
FROM(
SELECT
o.org
,p.names
,TotalDP = SUM(p.datapoint) OVER(PARTITION BY o.org,p.names)
,Rn = ROW_NUMBER() OVER(PARTITION BY o.org,p.names ORDER BY (SELECT 1))
FROM OrgPhysicianMappingtbl o
JOIN PhysicianDatatbl p on o.physician=p.physician)X WHERE X.Rn = 1