Group By from two tables [closed] - sql

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a requirement to show a report in the following format from the two different tables as shown below, the below report should count the order numbers by branch.
===================================================================
Branch OrdersCountInTable1 OrdersCountInTable2
===================================================================
100 5 2
200 10 10
300 12 11
how can i achieve this using a sqlquery?
Following are the columns in the tables:
Table1:
________
- Branch
- OrderNo
Table2
__________
- Branch
- OrderNo
Table1 Data:
===============================
Branch OrderNo
===============================
100 1000
100 1001
200 2001
100 1003
Table2 Data:
===============================
Branch OrderNo
===============================
100 1000
200 2001
100 1003
We just want to reconcile orders from both the tables!!
Thanks for any valuable feedbacks.

One more or less generic way to do it
SELECT COALESCE(t1.branch, t2.branch) branch,
COALESCE(t1.ordercount, 0) OrdersCountInTable1,
COALESCE(t2.ordercount, 0) OrdersCountInTable2
FROM
(
SELECT branch, COUNT(orderno) ordercount
FROM Table1
GROUP BY branch
) t1 FULL JOIN
(
SELECT branch, COUNT(orderno) ordercount
FROM Table2
GROUP BY branch
) t2
ON t1.branch = t2.branch
Assumption is that tables may not have entries for all branches. That's why FULL JOIN is used.

Do like this using SUM aggregate function and UNION ALL operator
SELECT Branch,
SUM( CASE tag WHEN 'table1' THEN 1 ELSE 0 END) as OrdersCountInTable1,
SUM( CASE tag WHEN 'table2' THEN 1 ELSE 0 END) as OrdersCountInTable2
FROM
(
SELECT Branch,'table1' as tag
FROM Table1
UNION ALL
SELECT Branch,'table2' as tag
FROM Table2
) z
GROUP BY Branch
ORDER BY Branch

Try it with a union nested query:
select
Branch, count(Orders1) OrdersCountInTable1, count(Orders2) OrdersCountInTable2
from (
select Branch,OrderNo Orders1,NULL Orders2 from Table1
union
select Branch,NULL Orders1,OrderNo Orders2 from Table2
) t
group by Branch

Related

How to use group by with case statement [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Improve this question
I have a table with following fields
CREATE TABLE Tblstock
( ID int , SlNo int, Storage varchar(10), stock int);
insert into Tblstock values
(1, 1, 'STORE', 100),
(2, 1, 'Floor 1', 20),
(3, 2, 'STORE', 2000),
(4, 2, 'Floor 1', 40);
I have to dynamically update the left over quantity in store after it got consumed on floor1, I have written a code to calculate qty in store using below mentioned query,
SELECT (
(SELECT CASE WHEN COUNT(B.SlNo) > 1 OR B.Storage = 'STORE' THEN SUM(B.Stock)END FROM TblStock B GROUP BY B.SlNo) -
(SELECT CASE WHEN COUNT(B.SlNo) > 1 OR B.Storage <> 'STORE' THEN SUM(B.Stock)END FROM TblStock B GROUP BY B.SlNo))
However it is not generating the desired result and throwing error
Can anybody help to write it properly so that I get single value of remaining quantity in store
You just need a straight-forward grouping and conditional aggregation
SELECT
s.SlNo,
Total = SUM(CASE WHEN s.Storage = 'STORE' THEN s.Qty ELSE -s.Qty END)
FROM TblStock s
GROUP BY
s.SlNo;
db<>fiddle
Assuming what you are trying to do is to deduct the quantity (qty) in storage called store by the sum of the rest of the other storage. I could think of a query like this:
select *,
(Qty - (select sum(b.Qty) from tblstock as b
where b.Storage <> 'store'
and b.SINo = a.SINo
group by b.SINo)) as remainingQty
from tblstock as a
where a.Storage = 'store' group by a.SINo
The query above, with the following input:
ID
SINo
Storage
Qty
1
1
store
100
2
1
floor 1
20
3
1
floor 2
30
4
2
store
100
5
2
floor 1
40
6
2
floor 2
50
It produces the following output:
ID
SINo
Storage
Qty
remainingQty
1
1
store
100
50
4
2
store
100
10
You can find the SQLFiddle here.
Note:
If you are want to avoid subquery and have the urge to chug in join fiddle:
select a.id,
a.SINo,
a.Storage,
a.Qty,
c.Qty,
(a.Qty - c.Qty) as remainingQty
from tblstock as a
join
(select b.SINo,
sum(b.Qty) as Qty
from tblstock as b
where b.Storage <> 'store'
group by b.SINo) as c
on c.SINo = a.SINo
where a.Storage = 'store' group by a.SINo

Create CASE WHEN labels based on DISTINCT values in a particular column [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have data of the following form:
ID
Category
Amount
1
A
100
1
B
200
1
B
150
1
C
500
2
B
20
3
A
100
1
B
100
I wish to GROUP BY the column ID, find out the DISTINCT types of Category present for each ID group and create a new column where I can create the following classification labels for each grouped ID based on the unique or distinct categories present and also calculate the corresponding sum of amount for each grouped ID. So the output should be the follows:
ID
Classification
Sum of Amount
1
ALL
950
1
B only
20
1
A and B only
200
I tried the following SQL code but it doesn't work, most likely because DISTINCT() command within a CASE WHEN statement cannot consider multiple values.
My query:
SELECT
ID,
(CASE WHEN DISTINCT(CATEGORY) IN ("A") then "A Only" WHEN WHEN DISTINCT(CATEGORY) IN ("B") THEN "B only"..........)
SUM(AMOUNT)
FROM Table
GROUP BY 1,2
I have tried multiple ways of using the DISTINCT statement with CASE WHEN but none of them works.
Hmmm . . . How about this?
select id,
(case when min(category) = max(category)
then min(category) || ' only'
when count(distinct category) = 3
then 'All'
when min(category) is NULL
then 'None'
else min(category) || ' and ' || max(category)
end)
from t
group by id;

SQL select column of attributes with latest date [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a table with multiple tenants and some tenants have an other expiration date, the rest in the table is for every tenant the same. I want to select the tenant with only the latest expiration date.
This is my code:
SELECT DISTINCT
property.scode AS "M nr",
tenant.scode AS "Contract nr",
unit.scode AS "Unit",
commamendments.DTSTART AS "Starting date",
sqft.DTDATE AS "Expiry date",
sqft.DSQFT0 AS "Area"
FROM
property
LEFT JOIN unit ON unit.hproperty = property.hmy
LEFT JOIN unitxref ON unitxref.hunit = unit.hmy
LEFT JOIN commamendments ON commamendments.hmy = unitxref.hamendment
LEFT JOIN tenant ON tenant.hmyperson = commamendments.htenant
JOIN attributes ON attributes.HPROP = property.hmy
JOIN sqft ON sqft.hpointer = unit.hmy
WHERE property.scode = '481'
AND sqft.DSQFT0 != '0'
AND ('9/30/2017 12:00:00 AM' BETWEEN commamendments.DTSTART AND commamendments.DTEND)
ORDER BY commamendments.DTEND`
As output I want a table with
Mnr Contract nr Unit Starting date Expiry date Area
481 1 1 9-10-2017 12-31-2018 400
481 2 2 8-10-2017 12-31-2019 500
.....
What I now receive is:
Mnr Contract nr Unit Starting date Expiry date Area
481 1 1 9-10-2017 12-31-2018 400
481 1 1 9-10-2017 09-20-2018 400
481 2 2 8-10-2017 12-31-2019 500
481 2 2 8-10-2017 1-31-2018 500
.....
Since you didn't specify which RDBMS you are working on and the table schema, then you can do this:
SELECT t1.tenantId, t1.ExpiryDate
FROM tenants AS t1
INNER JOIN
(
SELECT tenantId, MAX(ExpiryDate) AS LatestExpiryDate
FROM tablename
GROUP BY tenantId
) AS t1 ON t1.tenantId = t2.tenantId, t1.ExpiryDate = t2.LatestExpiryDate;
The inner join will give the latest date for each tenant id, and then you can join with the original query to get only those with the latest date.
(You didn't specify the table schema so I had to guess the columns' names, but I hope you got the idea).
Use Row_Number() to find the latest record of your tenants
Select * from (
Select *,Row_number() over(Partition by Tenants order by expirationdate desc) as rn from tablea
) x
Where rn = 1

merge two tables with no primary key but same amount of rows [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
i have two tables, looking like that. "Value1" is something like a 2nd key, ID + Value1 = "Primary" key, but its not in the table setup and the Value1 Field is missing in the 2nd table, so i can't join it.
But the first and 2nd table has always the same amount of rows and the exact same order!
Table 1:
ID Value1 Value2
10 1 100
10 2 200
20 1 250
30 1 150
30 2 125
Table 2:
ID Value 3
10 50
10 60
20 70
30 80
30 25
As the result i want to that the 2nd table is merged with the first table:
ID Value1 Value2 Value3
10 1 100 50
10 2 200 60
20 1 250 70
30 1 150 80
30 2 125 25
How to do this in SQL? Is it possible with a simple join/union, without creating new tables or something?
In general, in the absence of a column to JOIN by, you cannot simply merge the two tables together. Even though both tables have the same number of records and they appear ordered, in practice most RDBMS make no guarantee about the order in which each record would be either stored or selected.
You should rethink your database design and include a primary/foreign key in the 2 tables.
In TSQL you can write as:
;with CTEtab1 as
(select
ID,
Value1,
Value2,
row_number() over (order by Id asc) as rownum
from tab1)
,CTEtab2 as
(select
ID,
Value3,
row_number() over (order by Id asc) as rownum
from tab2)
select T1.Id,T1.Value1,T1.Value2,T2.Value3
from
CTEtab1 T1
join CTEtab2 T2
on T1.rownum=T2.rownum
Demo
You can do this with a simple join statement
SELECT table1.ID, table1.Value1, table1.Value2, table2.Value3
FROM table1
INNER JOIN table2
ON table1.ID = table2.ID;
though I'd still suggest altering the tables to make them have primary and foreign keys that connect them properly.

select only and only specific record in oracle [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I have a table with truck and locations , each truck can have many records with each location:
ex:
truck | location
----------------
60111 | 1
60111 | 2
60111 | 3
60111 | 4
60222 | 1
60222 | 2
....etc
I want to select the trucks with ONLY locations in (1,2).
in my example the return must be 60222 ONLY
how to do this?
Note: I want a dynamic solution not hard coded.
A solution similar to the one of Patrick Hofman is to move the logic in the HAVING clause
SELECT truck
FROM table
GROUP BY truck
HAVING COUNT(DISTINCT location) = 2
AND SUM(CASE WHEN location IN (1, 2) THEN 0 ELSE 1 END) = 0
The first condition return the truck with only two distinct location, not checking their values, the second condition force those location to be 1 and 2
This will select trucks that have exactly locations 1 and 2:
select t1.truck
from truck_location t1
where t1.location in (1, 2)
group by truck
having count(distinct t1.location) = 2
and count(distinct t1.location) = (select count(*)
from truck_location t2
where t2.truck = t1.truck);
The distinct inside the count() is only necessary if a truck could be assigned to the same location twice. If the combination truck/location is guaranteed to be unique this is not necessary.
SQLFiddle: http://sqlfiddle.com/#!15/b865f/1
select distinct truck
from
my_table
where
truck not in
(
select distinct truck
from my_table
where location not in (1, 2)
)
You can group by the truck, filter on the location and check the result is 2:
select truck
from table
where location in (1, 2)
group
by truck
having count(distinct location) = 2