I have a table called cia with 2 columns:
Column 1 ('Name') has the names of all countries in the world.
Column 2 ('area')has the size of those countries in m^2.
I want to find the biggest and smallest country. To find those I need to enter the following Queries:
SELECT Name, MAX(area) FROM cia
My other query:
SELECT Name, MIN(area) FROM cia
Now obviously I could do
SELECT MIN(area), MAX(area) FROM cia
however, I wouldn't get the corresponding name to my values then. Is it possible to get an output like this
Country | Fläche
Afghanistan | lowest value of column 'area'
China | highest value of column 'area'
This is the minimum size:
select min(area) from cia;
And this the maximum:
select max(area) from cia;
So:
select * from cia
where area = (select min(area) from cia)
or area = (select max(area) from cia)
order by area;
You can try this query:
CREATE TABLE area (name varchar(50), area int);
insert into area values ('Italy', 1000);
insert into area values ('China', 10000);
insert into area values ('San Marino', 10);
insert into area values ('Ghana', 3333);
select main.* from area main
where
not exists(
SELECT 'MINIMUM'
FROM area a2
where a2.area < main.area
)
or
not exists(
SELECT 'MAXIMUM'
FROM area a3
WHERE a3.area > main.area
)
order by area desc
In this way write only two subqueries. Other ways can go in error with other DBMS (no use of GROUP BY to show Name)
Go to Sql Fiddle
EDIT:
Sorry, my first thought was wrong. But this works.
SELECT Typ = 'MaxValue', * FROM (SELECT TOP 1 Name, area FROM cia ORDER BY area DESC) tmp1
UNION ALL
SELECT Typ = 'MinValue', * FROM (SELECT TOP 1 Name, area FROM cia ORDER BY area ASC) tmp2
You obviously have to hit the table twice, but there is no need for three hits.
select case Area when MaxArea then 'Largest' else 'Smallest' end Rating, b.Name as Country, b.Area
from(
select Max( Area ) as MaxArea, Min( Area ) as MinArea
from Cia a
) S
join Cia b
on b.Area = s.MaxArea
or b.Area = s.MinArea;
Related
I have a table of businesses, and each business can have up to 3 phone numbers. I want to find any duplicate phone numbers, but since the phone numbers are in different columns I don't think I can make the classic GROUP BY query work.
Sample data:
ID
Business_Name
phone_main
phone_mobile
phone_tollfree
1
John's Donuts
555-551-5555
555-551-5556
null
2
John's Bakery
555-551-5557
555-551-5555
null
3
SuperBake!
555-300-1005
null
555-551-5555
4
Grocery Fred
555-223-5511
555-334-5555
null
In this case I want to identify records 1, 2, and 3 as being the same. Simply identifying the phone number 555-551-5555 as a number with duplicates would be fine, as I can do a subquery or the calling program can use the phone number and send a new query getting all records with 555-551-5555 in any of the 3 phone columns.
This is on MariaDB if it matters.
Edit, (adding my current flailing attempt since someone seems to really want it):
Here's what I have right now:
SELECT ID, phone_main, phone_mobile, phone_tollfree
(
SELECT COUNT(*) FROM businesses b
WHERE (
phone IS NOT NULL AND (b.phone_mobile=phone OR b.tollfree=phone )
)
OR (
phone_mobile IS NOT NULL AND (b.phone=phone_mobile OR b.phone_tollfree=phone_mobile)
)
OR (
phone_tollfree IS NOT NULL AND (b.phone=phone_tollfree OR b.phone_mobile=phone_tollfree)
)
) cnt
from business HAVING cnt > 1
Problems with this:
It seems to be returning every row in my table.
It won't find duplicates within a single column.
How about uniting all the phone columns into one an then counting the reoccurrences?
I Didn't run the code but it might give you a direction...:
SELECT phone, COUNT(phone)
FROM (
SELECT phone_main as phone FROM SampleData
UNION ALL
(SELECT phone_mobile as phone FROM SampleData
ORDER BY City;
UNION ALL
SELECT phone_tollfree as phone FROM SampleData
ORDER BY City; and )
)
GROUP BY phone
E.g.:
SELECT DISTINCT x.*
FROM my_table x
JOIN my_table y
ON y.id <> x.id
AND
( y.phone_main IN(x.phone_main,x.phone_mobile,x.phone_tollfree)
OR y.phone_mobile IN(x.phone_main,x.phone_mobile,x.phone_tollfree)
OR y.phone_tollfree IN(x.phone_main,x.phone_mobile,x.phone_tollfree)
);
You can do:
with
l as (
select *, least(phone_main, phone_mobile, phone_tollfree) as p
from t
)
select *
from l
where p in (select p from l group by p having count(*) > 1)
i am trying to display both queries and displaying all results into one
this is what i want to achieve
this is the query i used, but union takes the common ones only, but i want both from query 1 and query 2.
select * from demo a where ( name, dob ) in ( select name,dob from demo group by name, dob having count(*) > 1 )
UNION
select * from demo a where ( name, mname) in ( select name, mname from demo group by name, mname having count(*) > 1 )
order by name ASC
The table structure is as below,
My first SQL query is as below,
SELECT DISTINCT(IndustryVertical)
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City
ORDER
BY `IndustryVerticalCount` DESC
by running the above query I'm getting the below,
What I'm trying to achieve is to get the List of all the DISTINCT CITY with ONLY ONE MAX(IndustryVerticalCount) and IndustryVertical.
Tried several things with no hope.
Anyone, please guide me.
There're several records in each City values. what I'm trying to achieve is that getting,
All the distinct City Values
The MAX COUNT of industryVertical
Name of industryVertical
The record I'm getting is as below,
What I'm trying to get,
The above record is reference purpose. Here, you can see only distinct city values with only one the vertical name having max count.
Since you are using group by, it will automatically select only distinct rows. Since you are using group by on two columns, you will get rows in which only combination of both columns is distinct.
What you now have to do is use this resulting table, and perform a query on it to find the maximum count grouped by city.
SELECT IndustryVertical, IndustryVerticalCount, City from
( SELECT IndustryVertical
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City) as tbl where IndustryVerticalCount IN (Select max(IndustryVerticalCount) from ( SELECT IndustryVertical
, COUNT(IndustryVertical) AS IndustryVerticalCount
, City
FROM `records`
WHERE City!=''
GROUP
BY IndustryVertical
, City) as tbl2 where tbl.City=tbl2.city)
This may not be the most efficient method, but I think it will work.
How about this? I think it should be worked:
DECLARE #DataSet TABLE (
City VARCHAR(50),
IndustryVertical VARCHAR(50),
IndustryVerticalCount INT
)
INSERT INTO #DataSet SELECT 'Bangalore', 'Consumer Internet', 279
INSERT INTO #DataSet SELECT 'Bangalore', 'Technology', 269
INSERT INTO #DataSet SELECT 'Bangalore', 'Logistics', 179
INSERT INTO #DataSet SELECT 'Mumbai', 'Technology', 194
INSERT INTO #DataSet SELECT 'Mumbai', 'Consumer Internet', 89
SELECT
table_a.*
FROM #DataSet table_a
LEFT JOIN #DataSet table_b
ON table_a.City = table_b.City
AND table_a.IndustryVerticalCount < table_b.IndustryVerticalCount
WHERE table_b.IndustryVerticalCount IS NULL
I think you simply want a HAVING clause:
SELECT r.IndustryVertical,
COUNT(*) AS IndustryVerticalCount,
r.City
FROM records r
WHERE r.City <> ''
GROUP BY r.IndustryVertical, r.City
HAVING COUNT(*) = (SELECT COUNT(*)
FROM records r2
WHERE r2.City = r.City
ORDER BY COUNT(*) DESC
LIMIT 1
)
ORDER BY IndustryVerticalCount DESC;
I have a table in which I have 3 columns
ID Amount District
1 100 A
2 500 B
1 250 A
2 240 B
1 100 A
Now I want to display Subtotal of distinct district and Grand total. Please guide me how should I write my sql query.
I want to show output as-
District Subtotal Grand Total
A 450
B 740 1190
You can use the SUM function to get the grand total, like this:
SELECT SUM(Amount) FROM data;
That'll return a single row containing a single number, the total of all of the Amounts in your entire table.
To get the per-district total, combine SUM with a GROUP BY clause:
SELECT SUM(Amount), District FROM data GROUP BY District;
This will return a table with one row for each district containing the total for that district.
Declaring the sample table and insert some data
DECLARE #tbl TABLE (ID INT, Amount INT, District CHAR(1))
INSERT #tbl
SELECT 1, 100, 'A' UNION ALL
SELECT 2, 500, 'B' UNION ALL
SELECT 1, 250, 'A' UNION ALL
SELECT 2, 240, 'B' UNION ALL
SELECT 1, 100, 'A'
Query
SELECT DISTINCT t.District,
CASE WHEN ID = (SELECT TOP 1 ID FROM #tbl
WHERE District = t.District
ORDER BY ID DESC)
THEN (SELECT SUM(Amount)
FROM #tbl
WHERE ID <= t.ID
AND District = t.District)
ELSE ' ' END AS [Subtotal],
CASE WHEN ID = (SELECT TOP 1 ID FROM #tbl
ORDER BY District DESC)
THEN (SELECT SUM(Amount)
FROM #tbl)
ELSE ' ' END AS [Grand Total]
FROM #tbl AS t
You can do the same thing for MySQL but instead of using TOP you need to use LIMIT
If you want the data in this format you can try using below code :
SELECT District As 'District', SUM(Amount) as 'Total'
FROM tbl
GROUP BY District
UNION
SELECT 'Grand Total', sum(Amount)
FROM tbl
I am having a table with following schema:
CUSTOMERS (id INT, name VARCHAR(10), height VARCHAR(10), weight INT)
id is the primary key. I want to find out rows in which people who are having exactly same name, same height and same weight. In other words, I want to find out duplicates with-respect-to name, height and weight.
Example table:
1, sam, 160, 100
2, ron, 167, 88
3, john, 150, 90
4, sam, 160, 100
5, rick, 158, 110
6, john, 150, 90
7, sam, 166, 110
Example Output:
Now since there are people with same name, same height and same weight:
sam (id=1), sam (id=4)
and
john (id=3), john (id=6)
I want to get these ids. It is also okay if I get only one id per match (i.e. id=1 from first match and id=3 from second match).
I am trying this query but not sure if it is correct or not.
SELECT id
FROM customers
GROUP BY name, height, weight
Try this (valid for sql server):
SELECT
t.NAME,
'Ids = '+
(
SELECT cast(Id as varchar)+','
FROM Customers c
WHERE c.NAME = t.NAME AND c.Weight = t.Weight AND c.Height = t.Height
FOR XML PATH('')
)
FROM
(
SELECT Name, height, weight
FROM Customers
GROUP BY Name, height, weight
HAVING COUNT(*) > 1
) t
OR
as you asked - only one Id per match
SELECT
t.NAME,
c.Id
FROM
(
SELECT Name, height, weight
FROM Customers
GROUP BY Name, height, weight
HAVING COUNT(*) > 1
) t
JOIN Customers c ON t.NAME AND c.Weight = t.Weight AND c.Height = t.Height
SELECT *
FROM customers C
INNER JOIN
(
SELECT name, height, weight
FROM customers
GROUP BY name, height, weight
HAVING COUNT(*) > 1
) X ON C.name = X.name AND C.height = X.height AND C.weight = X.weight
SELECT c.*
FROM customers c
JOIN (
SELECT name, height, weight
FROM
GROUP BY name, height, weight
HAVING count(*) > 1
) t ON c.name = t.name and c.height = t.height and c.weight = t.weight
you are on the right way:
SELECT min(id)
FROM customers
GROUP BY name, height, weight
HAVING COUNT(*) > 1
I don't know what you are using since you tagged several databases.
In Sql server you won't be able to select the id without putting it in the SELECT.
so if you want to select other fields besides the ones in the group clasue you can use PARTITION BY. Something like this:
SELECT id,
ROW_NUMBER() OVER(PARTITION BY c.name, c.height, c.weight ORDER BY c.name) AS DuplicateCount
FROM customers c
This will give you the ids of the duplicates that you have with the same name, height and weight.
I'm not sure that this is faster that the other solutions though, but, you can profile it and compare.
If it is okay to get only one id per match as you say, you are close to solution:
SELECT
min( id )
,name, height, weight --<-- oncly if you need/want
FROM customers
GROUP BY name, height, weight
HAVING count(*) > 1