How to get the Total count without distinct? - sql-server

Here is the fiddle
I have a table as
TABLE_MAIN
+-----+----------+---------+
| id | name | phase |
+-----+----------+---------+
| 101 | Bolt | PHASE 1 |
| 102 | Nut | PHASE 1 |
| 103 | Screw | PHASE 2 |
| 104 | Hex BOLT | PHASE 2 |
| 105 | Rubber | PHASE 3 |
| 106 | Aluminum | PHASE 3 |
| 107 | Slate | PHASE 3 |
| 108 | Pen | PHASE 3 |
| 109 | Pencil | PHASE 3 |
+-----+----------+---------+
TABLE_ERROR
+-----+----------+---------+
| id | name | phase |
+-----+----------+---------+
| 101 | Bolt | PHASE 1 |
| 102 | Needle | PHASE 1 |
| 101 | Bolt | PHASE 3 |
| 102 | Needle | PHASE 3 |
| 104 | Bolt | PHASE 3 |
| 105 | Rubber | PHASE 3 |
| 105 | Plastic | PHASE 3 |
| 106 | Aluminum | PHASE 3 |
| 106 | Steel | PHASE 3 |
| 106 | Cooper | PHASE 3 |
+-----+----------+---------+
Now I'm trying to find the number of times the ID of PHASE 3 in table_error appearing in table_main for each phase. If the ID is repeating, It should get added to the total count.
Expected
+---------+-----------------+-------+
| phase | already_present | total |
+---------+-----------------+-------+
| PHASE 1 | 2 | 8 |
| PHASE 2 | 1 | 8 |
| PHASE 3 | 5 | 8 |
+---------+-----------------+-------+
I have tried
SELECT phase, count(*) AS already_present, sum(count(*)) OVER () AS total
FROM table_main
WHERE id IN (
SELECT id
FROM table_error
WHERE phase = 'PHASE 3'
)
GROUP BY phase
But it is giving me,
+---------+-----------------+-------+
| phase | already_present | total |
+---------+-----------------+-------+
| PHASE 1 | 2 | 5 |
| PHASE 2 | 1 | 5 |
| PHASE 3 | 2 | 5 |
+---------+-----------------+-------+

Hope this helps you
select tm.phase, count(tm.id) AS already_present, SUM(count(tm.id)) OVER() as total
from table_main tm
inner join table_error te on te.id = tm.id and te.phase = 'PHASE 3'
group by tm.phase

Related

Design lookup table in SQL Server

I am trying to design EAV database for my website. Here are tables
Category
-------------------------
| Id | Title |
|-----------------------|
| 1 | Supplier |
| 2 | Material |
| 3 | RAM |
| 4 | CPU |
| 5 | Product |
-------------------------
Item
-------------------------
| Id | Category_Id |
|-----------------------|
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 2 |
| 6 | 3 |
| 7 | 3 |
| 8 | 4 |
| 9 | 4 |
| 10 | 4 |
| 11 | 5 |
| 12 | 5 |
-------------------------
AttributeType
-------------------------
| Id | Title |
|-----------------------|
| 1 | String |
| 2 | Text |
| 3 | Number |
| 4 | Lookup |
-------------------------
Attribute
-------------------------
| Id | Title |
|-----------------------|
| 1 | Name |
| 2 | Price |
| 3 | Suplier |
| 4 | RAM |
| 5 | CPU |
| 6 | Material |
| 7 | Address |
-------------------------
AttributeStringValue
-----------------------------------------------------------------
| Id | Attribute_Id | Item_Id | Value |
|---------------------------------------------------------------|
| 1 | 1 | 1 | Samsung |
| 2 | 1 | 2 | Nokia |
| 3 | 1 | 3 | Dell |
| 4 | 1 | 4 | Steal |
| 5 | 1 | 5 | Plastic |
| 6 | 1 | 6 | Ram 8GB |
| 7 | 1 | 7 | Ram 16GB |
| 8 | 1 | 8 | Core I3 |
| 9 | 1 | 9 | Core I5 |
| 10 | 1 | 10 | Core I7 |
| 11 | 1 | 11 | Mobile Nokia 1 |
| 12 | 1 | 12 | Laptop Dell 1 |
| 13 | 7 | 1 | Korea |
| 14 | 7 | 2 | Finland |
| 15 | 7 | 3 | USA |
-----------------------------------------------------------------
AttributeNumberValue
-----------------------------------------------------------------
| Id | Attribute_Id | Item_Id | Value |
|---------------------------------------------------------------|
| 1 | 1 | 11 | 100 |
| 2 | 1 | 12 | 500 |
-----------------------------------------------------------------
I want Mobile Nokia 1 and Laptop Dell 1 have supplier names that are lookuped to the items that have category is Supplier and I can config display column.
Ex:
Supplier have values: Nokia (address: Finland), Samsung(address: Korea)
"Mobile Nokia 1" has supplier column is items in the supplier category and I can configure to display "Address" column or "Title" column of supplier
Please give me advise to design lookup tables
Sorry for my english
Many thanks

SQL query to aggregate result from child table

I need to join 4 table and display records in my application
route1
-------------------------
| ID | MODE | SCH DATE |
| 1 | T | 1/12019 |
| 2 | T | 2/12019 |
| 3 | T | 2/12019 |
--------------------------
Stop2
----------------------------
| ID | routeID | LocationID |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 4 |
| 5 | 2 | 5 |
| 6 | 3 | 6 |
-----------------------------
StopOrder2
----------------------------
| ID | StopID | Wight |
| 1 | 1 | 100 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
| 4 | 2 | 1 |
| 5 | 3 | 2 |
| 6 | 3 | 3 |
| 7 | 4 | 2 |
| 8 | 4 | 3 |
| 9 | 5 | 2 |
| 10 | 5 | 3 |
| 11 | 6 | 2 |
| 12 | 6 | 3 |
-----------------------------
Location
| LocationID | Name, City, Zip
| 1 | name1,city1 1111
| 2 | name2,city2 2222
| 3 | name3,city3 333
-----------------------------
I want final result with each route have how many records and how many orders and sum of all order wight
-----------------------------------------
| RouteID | MODE | SCH DATE |No Of Stop |LastLocatioID|OrderCount|
| 1 | T | 1/12019 | 3 | 3 | 6 |
| 2 | T | 2/12019 | 2 | 5 | 4 |
| 3 | T | 2/12019 | 1 | 6 | 2 |
How can I write the SQL query I need?
All you need is a simple group by:
SELECT
r.ID AS RouteID,
r.MODE,
r.[SCH DATE],
COUNT(s.ID) AS [No Of Stop],
MAX(s.LocationID) AS [LastLocationID],
COUNT(o.ID) AS OrderCount
FROM
#route1 r
INNER JOIN #Stop2 s
ON r.ID = s.routeID
INNER JOIN #StopOrder2 o
ON s.ID = o.StopID
GROUP BY
r.ID,
r.MODE,
r.[SCH DATE]
Output:

Sum, Group by and Null

I'm dipping my toes into SQL. I have the following table
+------+----+------+------+-------+
| Type | ID | QTY | Rate | Name |
+------+----+------+------+-------+
| B | 1 | 1000 | 21 | Jack |
| B | 2 | 2000 | 12 | Kevin |
| B | 1 | 3000 | 24 | Jack |
| B | 1 | 1000 | 23 | Jack |
| B | 3 | 200 | 13 | Mary |
| B | 2 | 3000 | 12 | Kevin |
| B | 4 | 4000 | 44 | Chris |
| B | 4 | 5000 | 43 | Chris |
| B | 3 | 1000 | 26 | Mary |
+------+----+------+------+-------+
I don't know how I would leverage Sum and Group by to achieve the following result.
+------+----+------+------+-------+------------+
| Type | ID | QTY | Rate | Name | Sum of QTY |
+------+----+------+------+-------+------------+
| B | 1 | 1000 | 21 | Jack | 5000 |
| B | 1 | 3000 | 24 | Jack | Null |
| B | 1 | 1000 | 23 | Jack | Null |
| B | 2 | 3000 | 12 | Kevin | 5000 |
| B | 2 | 3000 | 12 | Kevin | Null |
| B | 3 | 200 | 13 | Mary | 1200 |
| B | 3 | 1000 | 26 | Mary | Null |
| B | 4 | 4000 | 44 | Chris | 9000 |
| B | 4 | 5000 | 43 | Chris | Null |
+------+----+------+------+-------+------------+
Any help is appreciated!
You can use window function :
select t.*,
(case when row_number() over (partition by type, id order by name) = 1
then sum(qty) over (partition by type, id order by name)
end) as Sum_of_QTY
from table t;

Row number by 3 distincts fields in SQL Server

I have this table:
| RecordLocator | DepartureStation | ArrivalStation | JourneyNumber | SegmentNumber | LegNumber | FlightNumber |
|---------------|------------------|----------------|---------------|---------------|-----------|--------------|
| DADABC | MAO | GRU | 2 | 1 | 1 | 1421 |
| CEDLDA | MAO | STM | 1 | 2 | 1 | 1643 |
| CEDLDA | GRU | MAO | 1 | 1 | 1 | 1640 |
| DADABC | GRU | FLN | 1 | 1 | 1 | 1848 |
| CEDLDA | BEL | SLZ | 1 | 2 | 3 | 1643 |
| DADABC | GIG | FOR | 1 | 2 | 3 | 1154 |
| CEDLDA | SLZ | FOR | 1 | 2 | 4 | 1680 |
| CEDLDA | FOR | REC | 1 | 2 | 5 | 1680 |
| DADABC | FOR | MAO | 1 | 2 | 4 | 1982 |
| CEDLDA | REC | SSA | 1 | 2 | 6 | 1680 |
| CEDLDA | STM | BEL | 1 | 2 | 2 | 1643 |
| DADABC | POA | GIG | 1 | 2 | 2 | 1201 |
| CEDLDA | SSA | GRU | 1 | 3 | 1 | 1817 |
| DADABC | FLN | POA | 1 | 2 | 1 | 1201 |
I want add a new column row number based on JourneyNumber, SegmentNumber and LegNumber, order by RecordLocator, for obtain this result:
| RecordLocator | DepartureStation | ArrivalStation | JourneyNumber | SegmentNumber | LegNumber | FlightNumber | rowNum |
|---------------|------------------|----------------|---------------|---------------|-----------|--------------|--------|
| CEDLDA | GRU | MAO | 1 | 1 | 1 | 1640 | 1 |
| CEDLDA | MAO | STM | 1 | 2 | 1 | 1643 | 2 |
| CEDLDA | STM | BEL | 1 | 2 | 2 | 1643 | 3 |
| CEDLDA | BEL | SLZ | 1 | 2 | 3 | 1643 | 4 |
| CEDLDA | SLZ | FOR | 1 | 2 | 4 | 1680 | 5 |
| CEDLDA | FOR | REC | 1 | 2 | 5 | 1680 | 6 |
| CEDLDA | REC | SSA | 1 | 2 | 6 | 1680 | 7 |
| CEDLDA | SSA | GRU | 1 | 3 | 1 | 1817 | 8 |
| DADABC | GRU | FLN | 1 | 1 | 1 | 1848 | 1 |
| DADABC | FLN | POA | 1 | 2 | 1 | 1201 | 2 |
| DADABC | POA | GIG | 1 | 2 | 2 | 1201 | 3 |
| DADABC | GIG | FOR | 1 | 2 | 3 | 1154 | 4 |
| DADABC | FOR | MAO | 1 | 2 | 4 | 1982 | 5 |
| DADABC | MAO | GRU | 2 | 1 | 1 | 1421 | 6 |
I tried this query:
SELECT
RecordLocator,
DepartureStation, ArrivalStation,
JourneyNumber, SegmentNumber,
LegNumber, FlightNumber,
(SELECT ((P.JourneyNumber + P.SegmentNumber + P.LegNumber))
FROM PAX P2
WHERE P2.RecordLocator = P.RecordLocator
AND P2.DepartureStation = P.DepartureStation
AND P2.ArrivalStation = P.ArrivalStation
AND P2.JourneyNumber = P.JourneyNumber
AND P2.SegmentNumber = P.SegmentNumber
AND P2.LegNumber = P.LegNumber
AND P2.FlightNumber = P.FlightNumber) AS rowNum
FROM
PAX P
I'm trying sum the columns JourneyNumber, SegmentNumber and LegNumber but does not work, i belive best way to do, is based on Recordlocator define a "weight" for the columns JourneyNumber > SegmentNumber > LegNumber, but i don't know how implement it.
In C# I know how to do it, using align for:
// First `for` - Journey
for(int i = 0; i < Journey.Count(); i++)
{
// Second `for` - Segment
for(int j = 0; j < Segment.Count(); j++)
{
// Third `for` - Leg
for(int k = 0; k < Leg.Count(); k++)
{
result = i + j + k;
}
}
}
Basically, breaking down your question into its parts, you want to re-start numbering for each RecordLocator, then you order it by the 3 fields you wanted in ascending order.
Overall, that's the idea of the ROW_NUMBER() which allows for ordering your records with a partition set for RecordLocator to re-start the numbering as needed. So, something like this should do it:
ROW_NUMBER() OVER(PARTITION BY RecordLocator ORDER BY JourneyNumber, SegmentNumber, LegNumber)
And your final SQL, therefore, becoming:
SELECT RecordLocator
, DepartureStation
, ArrivalStation
, JourneyNumber
, SegmentNumber
, LegNumber
, FlightNumber
, ROW_NUMBER() OVER(PARTITION BY RecordLocator ORDER BY JourneyNumber, SegmentNumber, LegNumber) AS rowNum
FROM PAX P
Hope this does the trick!

Multifilter SQL Server Pivot Count Query to table

I have never used SQL Pivot before and need help
I have the following data table (wkYield) in MS SQL Server 2012 which looks like:
| id | Trav_num | Part_num | Reason_code | Scrap | date |
| 1 | 123123 | 400 | cw_iweld | 1 | 1/1/2015 |
| 2 | 123122 | 400 | cw_iweld | 1 | 1/1/2015 |
| 3 | 123124 | 400 | cw_iweld | 0 | 1/7/2015 |
| 4 | 123124 | 400 | cw_iweld | 1 | 1/7/2015 |
| 5 | 123121 | 400 | cw_hole | 0 | 1/1/2015 |
| 6 | 123121 | 400 | cw_hole | 1 | 1/1/2015 |
| 7 | 123110 | 400 | cw_hole | 0 | 1/7/2015 |
| 8 | 123110 | 400 | cw_hole | 1 | 1/7/2015 |
| 9 | 123111 | 410 | cw_iweld | 0 | 1/1/2015 |
| 10 | 123111 | 410 | cw_iweld | 1 | 1/1/2015 |
| 11 | 123333 | 410 | cw_iweld | 1 | 1/1/2015 |
I would like to use SQL to pivot the data to count the # of rows and display like the following:
| Part_num | Reason_code | Week | Scrap=1 Cnt(reason)| Scrap=0 Cnt(reason)|
| 400 | cw_weld | 1 | 2 | 1 |
| 400 | cw_hole | 1 | 1 | 1 |
| 400 | cw_weld | 2 | 1 | 1 |
| 400 | cw_hole | 2 | 1 | 1 |
| 410 | cw_iweld | 1 | 2 | 1 |
And then the result should be placed in table wkYieldSum
I don't know for any given week number what the reason codes are (They change week to week but do have a lot of repeats.
All your help is very appreciated!
You can do this two ways one is conditional Aggregate another way is Pivot. I prefer Conditional Aggregate which more readable in my opinion
select Part_num,
Reason_code,
datepart(Week,[date]) as [Week],
count(case when Scrap=1 then 1 end) as [Scrap=1 Cnt(reason)],
count(case when Scrap=0 then 1 end) as [Scrap=0 Cnt(reason)],
From Yourtable
Group by Part_num,
Reason_code,
datepart(Week,[date])

Resources