How to split column into two columns based on unique ID? - sql

I have two IDs and I want to split those values into two different columns
Here is the example
I want to have one column name Cash for cash values and one column for Card values
id type value
1 cash 1000
2 card 3500
2 card 1600
1 cash 500
1 cash 300
Don't have any query because I don't know where to start from.
Expected results should be
id card cash
2 3500 null
1 null 1000
2 1600 null
1 null 500
1 null 300

Just use case expressions:
select id,
(case when type = 'card' then value end) as card,
(case when type = 'cash' then value end) as cash
from t;
Note: The ordering for the result set is indeterminate. You have not explained if the ordering is important to the question, but you seem to have the highest value for each id, then the second highest, and so on. If that is really desired:
order by row_number() over (partition by id order by value desc),
id desc

Related

How to find the changed value in history table sql

I want to find if the value changed for a particular ID
ID
PAYMENT METHOD
1
CASH
1
VISA
1
CASH
2
CASH
2
CASH
2
CASH
3
CHEQUE
3
VISA
3
VISA
4
CASH
4
CASH
4
CASH
For example, ID 1 and ID 3 changed their payment method and I want to write a query that can detect that change, thanks in advance
example for expected output:
ID
PAYMENT METHOD HAS CHANGED
1
VISA
3
CHEQUE
You can use:
SELECT id,
MIN(payment_method) KEEP (DENSE_RANK FIRST ORDER BY ROWNUM)
AS payment_method
FROM table_name
GROUP BY id
HAVING COUNT(DISTINCT payment_method) > 1
or:
SELECT *
FROM (
SELECT id,
payment_method,
ROWNUM AS ordering_column
FROM table_name t
)
MATCH_RECOGNIZE(
PARTITION BY id
ORDER BY ordering_column
MEASURES
FIRST(payment_method) AS payment_method
PATTERN (^ same+ diff)
DEFINE
same AS FIRST(payment_method) = payment_method,
diff AS diff.payment_method <> same.payment_method
);
(Note: ROWNUM should be replaced by a column that will identify a deterministic ordering in the rows for each ID such as a timestamp column; however, such a column is not present in your sample data so it cannot be used. ROWNUM will just number the rows in the order that the SQL engine processes them and that processing order may be non-deterministic.)
Which both output:
ID
PAYMENT_METHOD
1
CASH
3
CHEQUE
db<>fiddle here

Count Values From Column

I am trying to create a script in SQL Server that will count values under a column but I want it to still report missing values not counted.
Currently, I have the following setup with a group by, but it cuts the results in half:
select count(ID) as Count, Building, ID
from table
group by Building, ID
I want my output to show the count per ID as well as null values if there was nothing to count per ID.
Building ID
1234 1
1234 2
4567 3
4567 4
8910 5
0 6
Want the Output To Be:
Building ID Count
1234 1 2
1234 2 2
4567 3 2
4567 4 2
8910 5 1
0 6 0
The total population is 200,000. I want to see 200,000 records with the total counts per name or null values. When I run the above script, I obtain 1's per record.
Example: If ID 1 has a count of 2 and ID 2 has a count of 2, I want both IDs to show up as separate counts per ID.
You need to get the count from a sub-query and then join that sub-query
SELECT
CASE WHEN t1.building is null THEN 0
ELSE t1.building END AS Building,
t1.id,
CASE WHEN t1.building is null THEN 0
ELSE t2.count END AS Count
FROM table t1
JOIN (SELECT building, COUNT(*) as count
FROM table
GROUP BY building) AS t2 ON t2.building = t1.building OR (t2.building is null AND t1.building is null)
try
select count(name) as Count, ID, Building
from table
group by ID, Building

Grouping by multiple fields

I have a table of ParentID's which are products made by combining the required amount of the corresponding BaseID product.
Product table:
ParentID BaseID Required UOH
-------------------------------------
1 55 1 400
1 56 .5 400
2 55 1 400
2 57 1 400
3 58 1 0
I need to select the ParentID's where there are enough of each required base product (UOH) to create the Parent.
The Query should return
ParentID
----------------
1
2
The only way I know how to do this is by using a pivot view. Is there another or a better way to accomplish this?
Thanks
You can use group by and having:
select parentid
from table t
group by parentid
having sum(case when uoh < required then 1 else 0 end) = 0
The having clause counts the number of times where uoh is less than required. If the count is zero, then all base ids have sufficient amounts.

How to use subquery to populate column in Access query

I am working on an Access database which is used for forecasting purchases and I am trying to create a query in which would give me list of records with valid prices and row sums.
I am running into problems when I try to combine prices to quantities. I have following tables
Table that contains forecasting data (columns not relevant for this query omitted)
need_rows
ID product_id qty use_date
----------------------------
1 1 100 1.1.2014
2 1 50 15.1.2014
...
And table for prices
prices
ID product_id price valid_from
----------------------------------
1 1 1 1.12.2013
2 1 2 24.12.2013
3 1 5 10.1.2014
...
Query resulst should be something like below:
result of query
product_id use_date qty price sum
---------------------------------------
1 1.1.2014 100 2 200
1 15.1.2014 50 5 250
...
Meaning that I need to fetch valid price to each of the rows based on the use_date from need_rows and valid_from date from prices. Valid prices is the one that has valid_from date equal or most recent to use_date.
Below is one of the approaches I have tried with no luck.
SELECT prices.price
FROM prices
WHERE (((prices.product_id)=[product_id]) AND ((prices.valid_from)=
(SELECT Max(prices.valid_from) AS valid
FROM prices
WHERE (((prices.product_id)=[product_id]) AND ((prices.valid_from)<=[use_date]));).));
Any help is appreciated!
SELECT need_rows.Id
, need_rows.qty
, need_rows.product_id
, (SELECT TOP 1 price
FROM prices
WHERE need_rows.product_id = prices.product_id
AND need_rows.use_date >= prices.valid_from
ORDER BY prices.valid_from DESC) AS currentprice
FROM need_rows;

Sum of different column in SQL

We have an existing table with columns:
ItemCode nvarchar
Supplier1Price nvarchar
Supplier2Price nvarchar
Supplier3Price nvarchar
SelectedSupplier int (1, 2 or 3)
The table is used for canvassing from different suppliers. What I want to do is to get the sum of same items from selected suppliers.
Example:
ItemCode Supplier1Price Supplier2Price Supplier3Price SelectedSupplier
item-00 100 200 300 1
item-00 200 100 300 2
item-00 200 100 300 2
item-01 200 300 100 3
item-01 200 100 300 2
Result should be:
ItemCode Total
item-00 300
item-01 200
What I did is this:
select
ItemCode,
sum(SupplierPrice) as Total
from
(select
ItemCode,
case SelectedSupplier
when 1 then Supplier1Price
when 2 then Supplier2Price
when 3 then Supplier3Price
end) as SupplierPrice
from CanvassTable)
group by ItemCode
Note: First, code above selects all itemcodes and corresponding price (from selected supplier). The result then will be processed in order to get the sum of prices of each item.
It's working already, the problem is, I used subquery and I worry that when the table data grows the query will have poor performance. My question is is there any way I can do this without subquery?
If your query works, why not just do:
select
ItemCode,
SUM(case SelectedSupplier
when 1 then Supplier1Price
when 2 then Supplier2Price
when 3 then Supplier3Price
end) as SupplierPrice
from CanvassTable
group by ItemCode