SQL Server 2008 grouping based on 2 columns which contains null values - sql-server

My question is in the table structure below. All items grouped by storeName and storeId then displays the total of each item for each store. But some of the items not sold in some stores therefore displays NULL.. Is that possible to
display egg&bacon instead of NULL for the first 8 records in itemName column and
display coke for instead of NULL the second 8 in itemName column and so on.
I do not know the how many item they have. So it is dynamic.
I want to do this because I have created a crosstab report with pentaho report designer. It works fine but it expects data in order to display it properly. So each item must have 8 records, one for each store. So I can group it by store and itemname. So the report displays - or 0 for the items not sold for those stores.
what I have
storeId storeName itemName total
1 storeA egg&bacon 75
2 storeB NULL NULL
3 storeC egg&bacon 30
4 storeD NULL NULL
5 storeE NULL NULL
6 storeF egg&bacon 50
7 storeG NULL NULL
8 storeH NULL NULL
1 storeA coke 105
2 storeB coke 90
3 storeC coke 60
4 storeD NULL NULL
5 storeE coke 20
6 storeF coke 80
7 storeG NULL NULL
8 storeH NULL NULL
what I want (If the table below is not realistic, I can create a separate column to group them but again how?)
storeId storeName itemName total
1 storeA egg&bacon 75
2 storeB egg&bacon 0
3 storeC egg&bacon 30
4 storeD egg&bacon 0
5 storeE egg&bacon 0
6 storeF egg&bacon 50
7 storeG egg&bacon 0
8 storeH egg&bacon 0
1 storeA coke 105
2 storeB coke 90
3 storeC coke 60
4 storeD NULL 0
5 storeE coke 20
6 storeF coke 80
7 storeG NULL 0
8 storeH NULL 0
This is the sample SQL statement
SELECT storeId , storeName, itemName, total FROM STORE
LEFT OUTER JOIN
(
SELECT storeId, storeName, itemId, total FROM REVENUE_CENTER as RVC
LEFT OUTER JOIN MENU_ITEM_TOTAL as MIT ON STORE.storeId = MIT.storeId
) as subQ ON STORE.storeId = subQ.storeId
LEFT OUTER JOIN MENU_ITEM as MI ON MI.itemId = subQ.itemId
thanks in advance
Oz.

If you want to know you have zero egg&bacon in a store you must at least set the item name to 'egg&bacon'
to change null to zero in the total column you can use ISNULL(itemName, 0)
since storeid and name are constant you should only keep storeid in the table, and group by it (better performance, less data space) and keep store name in another table. That will change your group by statements to be based only on store ID.
Consider not saving records for items shat are now null, null - this is something your code should handle.

Related

T-SQL query to write case statements with different scenarios

I have 2 tables Test Table and Investigation table.
Test table has
ChildID AddressID TestID TestValue TestDate
1 1 1 20 08/04/2017
2 2 2 20 09/04/2017
2 2 3 10 10/04/2017
When a child has test value >=20 the system automatically generates a Investigation on address but cannot open when between 15 and 19.9
Investigation Table
ChildID InvestID AddressID Status
1 1 1 open
2 2 2 open
If I get a new incoming Test record for child id's this is how my table looks
ChildID AddressID TestID TestValue TestDate
1 1 1 20 08/04/2017
1 5 4 16 12/04/2017(New record)
2 2 2 20 09/04/2017
2 2 3 10 10/04/2017
2 3 5 19 12/04/2017(New Record)
Scenario 1
I want to select New records and show 'status'(new column) as 'New address' case where Test value is between 15 and 19.9 and test date is 90 days apart and address id is not equal for two tests. Don't select any record if the address is same.
Scenario 2
If the child has second testvalue between 15 and 19.9 with same addess id
ChildID AddressID TestID TestValue TestDate
3 6 10 16 08/04/2017
3 6 20 18 11/04/2017 (New Record)
Select the new records with status as 'New Case and New address'
Scenario 3
ChildID AddressID TestID TestValue TestDate
3 6 10 16 08/04/2017
3 6 20 18 11/04/2017
3 7 21 17 02/04/2018 (New record)
Show latest record status as 'new address' because it has different address.
So far I have written the query but I am unable to compare records and write case statements for 'Status column'. I am only able to select records.
Select childid,Testid,TestDate,
TestValue,addressid,lc.caseType,
DateDiff(Day,lead(Test) OVER (Partition by Childid order by TestDate desc),Testdate) as Datediff,
DateDiff(day,First_Value(Testdate) Over (Partition by Childid order by b2.Testdateasc),Testdate) as Datedif1
from Test T
Left Join Investigation I
on T.child=I.childid
and b.observationValue between 15 and 19.99
and Datedif1>=90 or Datediff>=90

get record according to date

I try this query according to date i have only column datecurrent in this record according to current date so there is almost 5 days record with different dates now i want to fetch record according to date i use this but this shows all records whereas i want to get record in specific dates
select c.Orderid,c.DateCurrent,c.Quantity,c.ItemCost,i.ItemCost*c.quantity
as Bill from CustomerOrder c inner join item i on i.ItemId=c.ItemId
inner join userinformation ui on ui.userid=c.userid
where c.datecurrent as fromdate > '2017-04-13' union all
select null,null,null,null,sum (i.ItemCost*c.Quantity) bill
from CustomerOrder c inner join item i on i.itemid=c.ItemId
inner join userinformation ui on ui.userid=c.userid where c.datecurrent as todate > '2017-04-15'
there is records of 16 date and above query shows 16 date records where i want only those records which is between 13 and 15 and same with other dates .. i try this query in winforms with datepicker
this is data
Orderid DateCurrent Quantity ItemCost Bill
101 2017-04-16 14:35:45.823 12 10 120
1093 2017-04-16 17:32:36.250 2 10 20
2093 2017-04-16 17:32:36.250 2 10 20
2094 2017-04-13 17:32:36.250 4 10 400
2095 2017-04-15 17:32:36.250 5 10 50
2096 2017-04-15 17:32:36.250 10 10 1000
2097 2017-04-14 17:32:36.250 12 10 120
NULL NULL NULL NULL 1210
this is i want to get data if i enter only dates between 13 and 15
Orderid DateCurrent Quantity ItemCost Bill
2094 2017-04-13 17:32:36.250 4 10 400
2095 2017-04-15 17:32:36.250 5 10 50
2096 2017-04-15 17:32:36.250 10 10 1000
2097 2017-04-14 17:32:36.250 12 10 120
NULL NULL NULL NULL 1210
I suspect that this does what you want:
select c.DateCurrent, sum(i.ItemCost * c.quantity) as Bill
from CustomerOrder c inner join
item i
on i.ItemId = c.ItemId
where c.datecurrent >= '2017-04-13'
group by grouping sets ( (c.DateCurrent), () );
This returns one row per date plus the total of all dates, along with the sum of the cost times quantity.

Merge with a preferred source

I'm using SSIS 2008 R2 for a few weeks now and I'm stuck at this moment.
I need to merge two tables from two different SQL Servers into a new table.
This is what I try to achieve:
Table 1:
Name Price Quantity
------------------------
Item 1 23 5
Item 2 50 2
Item 3 30 10
Table 2:
ID Name Price Quantity
------------------------------
101 Item 1 60 7
203 Item 3 80 15
Result:
ID Name Price Quantity
-------------------------------------
101 Item 1 60 7
NULL Item 2 50 2
203 Item 3 80 15
I've tried to use merge but that duplicates Item 1 and Item 3.
I'm trying to create it within Development Studio so there is no real code that I can show.
This is what I've created
Select T2.ID, T1.Name,Price=case when isnull(T1.Price,0)>isnull(T2.Price,0) then
isnull(T1.Price,0) else isnull(T2.Price,0) end,
Quantity=case when isnull(T1.Quantity,0)>isnull(T2.Quantity,0)
then isnull(T1.Quantity,0) else isnull(T2.Quantity,0) end
from Table1 T1
left outer join Table2 T2 on T1.Name=T2.Name

SQL Stored Procedures : Count, Join and group by but it is shown 'NULL'

I got stuck something about stored procedures I write a stored that i need to shot three columns of products count like this
SELECT
Count([TPDTN].[ProductName]) as 'Product Count',
[TPDTN].[CategoryID]
FROM
[TPDTN]
LEFT JOIN
[TPDCN] ON [TPDTN].[CategoryID] = [TPDCN].[libDocumentID]
GROUP BY
[TPDTN].[CategoryID], [TPDCN].[libDocumentID]
It shows results like this:
Product Count CategoryID
---------------------------
2 1
9 2
2 3
2 4
1 5
But I don't know how make it show
Product Count CategoryID libDocumentID
-----------------------------------------------
2 1 123456789
9 2 123456789
2 3 123456789
2 4 123456789
1 5 123456789
Producer ID (LibdocumentID) is from other table but when I SELECT [TPDCN].[libDocumentID] the value is NULL
Product Count CategoryID libDocumentID
------------------------------------------------
2 1 NULL
9 2 NULL
2 3 NULL
2 4 NULL
1 5 NULL
How can I solve it? Thank you
Just add it to the select, and if you don't need the NULL you need an INNER JOIN:
SELECT Count([TPDTN].[ProductName]) as 'Product Count',[TPDTN].[CategoryID], [TPDCN].[libDocumentID]
FROM [TPDTN]
inner join [TPDCN]
ON [TPDTN].[CategoryID] = [TPDCN].[libDocumentID]
GROUP BY [TPDTN].[CategoryID],[TPDCN].[libDocumentID]

Transact SQL - which Join to Use

I have two simple SELECT statements:
The first shows a list of Features.
SELECT * FROM Features
id name
-- ----
1 24 Hour Access
2 24 hour CCTV monitoring
3 Airport location
4 Break-Out Areas
5 Business Lounge
6 Business park location
snip..
and the second statement shows a list of feature information that has changed
SELECT
*
FROM
#SmartFeaturesToUpdate new_features
ORDER BY
new_features.centre_translation_id,
new_features.feature_id,
new_features.feature_selected
feature_id centre_translation_id feature_selected
---------- --------------------- ----------------
1 1 1
2 1 1
5 1 1
10 1 1
11 1 1
snip..
What I want to see is all of the features by centre translation.
Combining the tables gives me:
SELECT
*
FROM
#SmartFeaturesToUpdate new_features
LEFT JOIN Feature feature ON feature.id = new_features.feature_id
ORDER BY
new_features.centre_translation_id,
new_features.feature_id,
new_features.feature_selected
feature_id centre_translation_id feature_selected id name
---------- --------------------- ---------------- -- ----
1 1 1 1 24 Hour Access
2 1 1 2 24 hour CCTV monitoring
5 1 1 5 Business Lounge
10 1 1 10 Double Glazing
11 1 1 11 Elevator
snip..
The result above is missing feature id's 3 and 4, because they are not in the second list.
but the result I need is:
feature_id centre_translation_id feature_selected id name
---------- --------------------- ---------------- -- ----
1 1 1 1 24 Hour Access
2 1 1 2 24 hour CCTV monitoring
3 1 1 3 Airport Location
4 1 1 4 Break-Out Area
5 1 1 5 Business Lounge
snip..
How should I modify the third SELECT statement to acheive this and combine the results from both the features and feature information list?
As the comments alluded, I needed another table which linked Features to centre_translation_ids
First get all of the feature / centre_translation varients
SELECT
[centre_translation_id] = centre_translation.id,
feature.id,
feature.name
INTO #AllTheFeatures
FROM
CentreTranslation centre_translation
CROSS JOIN Feature feature
ORDER BY
centre_translation.id,
feature.id
Now we can simply perform the LEFT JOIN
SELECT
all_features.centre_translation_id,
all_features.id,
all_features.name,
smart_features.feature_selected
FROM
#AllTheFeatures all_features
LEFT JOIN #SmartFeaturesToUpdate smart_features ON smart_features.centre_translation_id = all_features.centre_translation_id AND
smart_features.feature_id = all_features.id
ORDER BY
all_features.centre_translation_id,
all_features.id
This gives the results:
centre_translation_id id name feature_selected
--------------------- -- ---- ----------------
1 1 24 Hour Access 1
1 2 24 hour CCTV monitoring 1
1 3 Airport location NULL
1 4 Break-Out Areas NULL
1 5 Business Lounge 1
Why don't you just put it in one query?
SELECT
centre_translation.id AS centre_translation_id,
feature.id,
feature.name,
smart_features.feature_selected
FROM
CentreTranslation centre_translation
CROSS JOIN Feature feature
LEFT JOIN #SmartFeaturesToUpdate smart_features
ON smart_features.centre_translation_id = all_features.centre_translation_id
AND smart_features.feature_id = all_features.id
ORDER BY
centre_translation.centre_translation_id,
feature.id

Resources