T-SQL : partitioning using a case statement - sql

I have the following table :
| RoomID | OrderID | Occupancy | Status |
+--------+---------+-----------+---------------+
| 01 | 101 | Vacant | inspection |
| 01 | 102 | Occupied | Preservation |
| 01 | 103 | Occupied | inspection |
| 01 | 104 | Vacant | inspection |
| 02 | 201 | Vacant | inspection |
| 02 | 202 | Occupied | inspection |
| 02 | 203 | Vacant | inspection |
| 03 | 301 | Vacant | inspection |
| 03 | 302 | Occupied | inspection |
| 03 | 303 | Occupied | Preservation |
| 03 | 304 | Occupied | Preservation |
| 04 | 401 | Occupied | inspection |
| 04 | 402 | Occupied | inspection |
| 04 | 403 | Vacant | Preservation |
| 04 | 404 | Occupied | inspection |
I need to pull my data on a RoomID level where the Occupancy = 'Occupied' and Status = 'Preservation' in any instance of a given RoomID.
The result should look like the following:
| RoomID | Flag |
+--------+---------+
| 01 | 1 |
| 02 | 0 |
| 03 | 1 |
| 04 | 0 |
I have an impression that this is easy but I cannot see it at the moment, thank you in advance for your help !

You can use conditional aggregation.
select roomid,
count(distinct case when Occupancy = 'Occupied' and Status = 'Preservation' then 1 end) flag
from tablename
group by roomid

You can also use the below query using UNION.
;with cte_1
AS
( SELECT DISTINCT RoomId
FROM YourTable
WHERE Occupancy='Occupied' AND Status='Predervation')
SELECT RoomId,1 Status
FROM cte_1
UNON
SELECT DISTINCT RoomId,0 Status
FROM YourTable t
WHERE NOT EXISTS(SELECT 1 FROM cte_1 c
WHERE t.RoomId=c.RoomId)

Related

Biguqery Row Number Perioding based on specific values

So i have a raw data like this.
| User_id | Month | Device
| 001 | 01 | A
| 001 | 02 | A
| 001 | 03 | B (Base)
| 001 | 04 | A
| 002 | 01 | C
| 002 | 02 | C
| 002 | 03 | B (Base)
| 002 | 04 | B (Base)
| 003 | 01 | A
| 003 | 02 | B (Base)
| 003 | 03 | A
| 003 | 04 | B (Base)
I want to create period that split by B (Base) Device. I thinking about using Row Number but breaks only if meet B or several B's.
The result i want will be like this
| User_id | Month | Device | rn
| 001 | 01 | A | 1
| 001 | 02 | A | 1
| 001 | 03 | B (Base)| 2
| 001 | 04 | A | 3
| 002 | 01 | C | 1
| 002 | 02 | C | 1
| 002 | 03 | B (Base)| 2
| 002 | 04 | B (Base)| 2
| 003 | 01 | A | 1
| 003 | 02 | B (Base)| 2
| 003 | 03 | A | 3
| 003 | 04 | B (Base)| 4
Is there any way we can populate rn like that?
You might consider below query.
SELECT * EXCEPT(flag), COUNTIF(flag) OVER w + 1 AS rn FROM (
SELECT *,
(LAG(Device) OVER w <> 'B' AND Device = 'B') OR
(LAG(Device) OVER w = 'B' AND Device <> 'B') AS flag
FROM sample_table
WINDOW w AS (PARTITION BY User_id ORDER BY Month)
) WINDOW w AS (PARTITION BY User_id ORDER BY Month)
ORDER BY User_id, Month;
+---------+-------+--------+----+
| User_id | Month | Device | rn |
+---------+-------+--------+----+
| 001 | 01 | A | 1 |
| 001 | 02 | A | 1 |
| 001 | 03 | B | 2 |
| 001 | 04 | A | 3 |
| 002 | 01 | C | 1 |
| 002 | 02 | C | 1 |
| 002 | 03 | B | 2 |
| 002 | 04 | B | 2 |
| 003 | 01 | A | 1 |
| 003 | 02 | B | 2 |
| 003 | 03 | A | 3 |
| 003 | 04 | B | 4 |
+---------+-------+--------+----+

Make a master record out of several duplicate records for each id

My table structure is as shown below
Id | Name | City | Country | State
01 | Bob | *NY* | null | null
01 | Bob | null | *US* | null
01 | Bob | null | null | *AL*
02 | Roy | *LA* | null | null
02 | Roy | null | *IN* | null
02 | Roy | null | null | *MG*
I want to generate two output records from the above table like below.
Id | Name | City |Country | State
01 | bob | NY | US | AL
02 | Roy | LA | IN | MG
You can use aggregation:
select id, name, max(city), max(country), max(state)
from t
group by id, name;

How many different Product has one Market SQL

I try to get an output where there are the Market_id and the number of different Product_id of the market
Table1
| Market_id | Product_id |
| 01 | 105 |
| 01 | 12 |
| 01 | 105 |
| 02 | 34 |
| 02 | 34 |
| 03 | 22 |
| 03 | 22 |
| 03 | 22 |
| 03 | 18 |
output like this
|01 | 2 |
|02 | 1 |
|03 |2 |
and for example if i have a market_id has not Product_id how can i return
| 05 | 0 |
Thanks
Here is the Solution:
select market_id,count(distinct product_id) as count from TableName group by market_id

TSQL : conditional query

I am trying to find a way to get results where the Occupancy in the latest Inspection_date and the one before the last are not equal.
In this example only number RoomID 2 will be the only result because: the Occupancy for OrderID 201 = 'Vacant' <> to the Occupancy for OrderID 202 = 'Occupied'.
I have the beginning of the query but cannot seem to find a good logic to end the query.
| RoomID | OrderID | Occupancy | rn |
+--------+---------+-----------+----+
| 01 | 101 | Vacant | 1 |
| 01 | 102 | Vacant | 2 |
| 01 | 103 | Occupied | 3 |
| 01 | 104 | Vacant | 4 |
| 02 | 201 | Vacant | 1 |
| 02 | 202 | Occupied | 2 |
| 02 | 203 | Vacant | 3 |
| 03 | 301 | Occupied | 1 |
| 03 | 302 | Occupied | 2 |
| 03 | 303 | Occupied | 3 |
| 03 | 304 | Occupied | 4 |
| 04 | 401 | Occupied | 1 |
| 04 | 402 | Occupied | 2 |
| 04 | 403 | Vacant | 3 |
| 04 | 404 | Occupied | 4 |
SELECT i.room_number, order_number, Occupancy , row_number() OVER(PARTITION BY room_number ORDER BY Inspection_date DESC) rn
FROM #inspection_data i
In SQL Server 2012+, you can use lag(), so something like this:
SELECT i.*
FROM (SELECT i.room_number, order_number, Occupancy ,
ROW_NUMER() OVER (PARTITION BY room_number ORDER BY Inspection_date DESC) as seqnum,
LAG(Occupancy) OVER (PARTITION BY room_number ORDER BY Inspection_date) as prev_Occupancy
FROM #inspection_data i
) i
WHERE prev_Occupancy <> Occupancy AND seqnum = 1 ;

SQL Oracle get data with more of one associated data

I've a table with some data like this:
| cod_1 | cod_2 |
-------------------------
| 1 | 03 |
| 2 | 07 |
| 2 | 09 |
| 3 | 09 |
| 4 | 01 |
| 4 | 02 |
| 4 | 08 |
In this case I need to get the cod_1 2 and 4 because they have more tahn one cod_2 associated.
You can do it like this:
SELECT cod_1
FROM tablename
GROUP BY cod_1
HAVING count(*) > 1