sql select 1 item from list - sql

i want to select a column from a table which can have another column reference many times.
select t1.name
from ccp.ENTITIES t1
Non
Albania
Australia
China
Czech Republic
Egypt
Germany
Greece
Group
Hungary
India
Ireland
Italy
Luxembourg
Malaysia
Malta
Netherlands
Portugal
Romania
Spain
Turkey
UK
US
this will give me a list of names of which i want 1 row from another table
v_networks_by_lm this table holds records with column t1.name and network. i want the column network only once for each item in the list. v_networks_by_lmcan hold many t1.name
entity name
a Spain
b Spain
c Spain
d Spain
e Spain
f Spain
g Spain
h Germany
i Germany
j Germany
k Germany
l Germany
m Germany
n Germany
o Germany
p UK
q Germany
r Spain
s Spain
t Portugal
u Portugal
v Portugal
q Portugal
from the above data which is in v_networks_by_lm i only want name returned once with any value of entity. but i want to pick the name from ENTITIES as it can be dynamic

I think aggregation does what you want:
SELECT MAX(n.network) as network, e.name
FROM ccp.ENTITIES e JOIN
ccp.v_networks_by_lm n
ON n.name = e.name
GROUP BY e.name;

Sounds like you want a subquery to get the single instance of name from the table, and then you do the join against entities.
Select sub.one_of_entity_values, sub.name
from ccp.entities e
inner join (
select max(entity) as one_of_entity_values, name
from v_networks_by_lm
group by name) sub on e.name = sub.name

Related

Can not use group by function

Data on Table:-
wkt Partners Team Opponent Runs Balls
1 S Hope & E Lewis WEST INDIES SOUTH AFRICA 43 66
2 S Hope & S Hetmyer WEST INDIES SOUTH AFRICA 70 79
3 D Bravo & S Hetmyer WEST INDIES SOUTH AFRICA 84 97
1 J Malan & Q Kock SOUTH AFRICA WEST INDIES 3 4
2 J Malan & F Plessis SOUTH AFRICA WEST INDIES 32 44
3 J Malan & R Dussen SOUTH AFRICA WEST INDIES 100 90
1 S Dhawan & R Sharma INDIA IRELAND 3 8
2 V Kohli & R Sharma INDIA IRELAND 102 70
I want to return the pair of partners, team they belong to, opponent they play against only once for each wkt where runs are highest for that particular wkt
For above table I'd like result as follow
wkt Partners Team Opponent Runs Balls
1 S Hope & E Lewis WEST INDIES SOUTH AFRICA 43 66
2 V Kohli & R Sharma INDIA IRELAND 102 70
3 J Malan & R Dussen SOUTH AFRICA WEST INDIES 100 90
Following is the code that I've used
SELECT wkt, Partners, Team, Opponent, max(Runs), Balls
FROM Partnerships
GROUP BY wkt
But I've been stuck with following error
Column 'Partnerships.Partners' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
How about row_number()?
select p.*
from (select p.*, row_number() over (partition by wkt order by runs desc) as seqnum
from Partnerships p
) p
where seqnum = 1;

Constructing the SQL query below

GOALS (~1700 rows)
YEAR COUNTRY NAME NUM_GOALS
-------------------------------------------
2018 England Harry Kane 6
2018 France Antoine Griezmann 4
2014 Argentina Lionel Messi 4
2014 Brazil Fred 1
2010 Germany Thomas Muller 5
2010 Japan Shinji Okazaki 1
1992 England Gary Linekar 6
CHAMPIONS (~500 rows)
YEAR COUNTRY NAME ROLE
-------------------------------------------------
2018 France Didier Deschamps Manager
2018 France Hugo Lloris Goalkeeper
2018 France Paul Pogba Midfielder
2014 Germany Joachim Loew Manager
2014 Germany Mesut Ozil Midfielder
2014 Germany Miroslav Klose Forward
2002 Brazil Da Silva Midfielder
1994 Brazil Da Silva Midfielder
1998 France Didier Deschamps Midfielder
Write a query showing all world cup winning players who have never scored a goal.
What I am unsure about is whether to use a join for this and whether there is a need to specify and ID's if a join is to be used.
I'd be grateful for extra clarification and help with this, or if my query needs any tweaking.
What I have tried:
This is what I came up with:
SELECT GOALS.NAME
FROM GOALS
INNER JOIN CHAMPIONS ON CHAMPIONS.COUNTRY = GOALS.NAME
WHERE GOALS.NUM_GOALS = 0;
Problems with your query:
the join condition does not look right
even if it was, it searches for players that had at least one world cup without scoring a goal - which is different from those that never scored a goal
You could use not exists:
select c.*
from champions c
where not exists (
select 1
from goals g
where g.country = c.country and g.name = c.name and g.num_goals > 0
)
This assumes that (country, name) tuples do identify a player.
On the other hand, if you want players that won a world cup without scoring a goal in that particular event, then you can either add a correlation condition on year, or use a straight join:
select c.*
from champions c
inner join goals g
on g.country = c.country
and g.name = c.name
and g.year = c.year
where g.num_goals = 0
Your ON condition is comparing CHAMPIONS.COUNTRY = GOALS.NAME, which is not a good comparison for joining these two tables. I would suggest doing this:
SELECT
GOALS.NAME
FROM
GOALS
INNER JOIN
CHAMPIONS
ON
CHAMPIONS.COUNTRY = GOALS.COUNTRY
WHERE
GOALS.NUM_GOALS = 0;

SQL- how would i Join these two queries

I have the following queries, and am attempting to join them
SELECT COUNTRY_NAME, COUNTRY_ID
FROM OEHR_COUNTRIES;
these results
COUNTRY_NAME CO
---------------------------------------- --
Argentina AR
Australia AU
Belgium BE
Brazil BR
Canada CA
Switzerland CH
China CN
Germany DE
Denmark DK
Egypt EG
France FR
HongKong HK
Israel IL
India IN
Italy IT
Japan JP
Kuwait KW
Mexico MX
Nigeria NG
Netherlands NL
Singapore SG
United Kingdom UK
United States of America US
Zambia ZM
Zimbabwe ZW
my second query
SELECT COUNTRY_ID, COUNT(COUNTRY_ID) AS "LCOUNT"
FROM OEHR_LOCATIONS
GROUP BY COUNTRY_ID;
results
CO LCOUNT
-- -------
US 4
SG 1
CA 2
CH 2
IT 2
MX 1
CN 1
DE 1
JP 2
IN 1
AU 1
UK 3
BR 1
NL 1
When i attempt to join these two results, so each country has the count after it
SELECT OEHR_COUNTRIES.COUNTRY_NAME, OEHR_COUNTRIES.COUNTRY_ID, COUNT(OEHR_LOCATIONS.COUNTRY_ID) AS LCOUNT
FROM OEHR_COUNTRIES
OUTER JOIN OEHR_LOCATIONS
ON OEHR_COUNTRIES.COUNTRY_ID = OEHR_LOCATIONS.COUNTRY_ID
ORDER BY LCOUNT;
i get this error
ON OEHR_COUNTRIES.COUNTRY_ID = OEHR_LOCATIONS.COUNTRY_ID
*
ERROR at line 4:
ORA-00904: "OEHR_COUNTRIES"."COUNTRY_ID": invalid identifier
ON OEHR_COUNTRIES.COUNTRY_ID = OEHR_LOCATIONS.COUNTRY_ID
*
ERROR at line 4:
ORA-00904: "OEHR_COUNTRIES"."COUNTRY_ID": invalid identifier
what is causing this error?
is there a simpler way to do what i am trying to achieve?
I assume this is something you need. It would list 0 for countries with no count. If you dont want to list countries with no count, use INNER JOIN
SELECT C.COUNTRY_NAME,
case
when L.LCOUNT is null
then 0
else L.LCOUNT
END as LCOUNT
FROM OEHR_COUNTRIES C
LEFT JOIN
(SELECT COUNTRY_ID, COUNT(COUNTRY_ID) AS LCOUNT
FROM OEHR_LOCATIONS
GROUP BY COUNTRY_ID) L
on C.COUNTRY_ID=L.COUNTRY_ID
order by LCOUNT DESC
You're missing the mandatory LEFT (or, in other scenarios, RIGHT) before the optional OUTER in the join syntax.
At the moment the word OUTER is being misinterpreted as a table alias, which is what is causing the error you're getting - there is, to the parser, now an OUTER.COUNTRY_ID but not a OEHR_COUNTRIES.COUNTRY_ID.
Add the missing word to stop it being seen as an alias, and to stop it defaulting to an inner join:
SELECT OEHR_COUNTRIES.COUNTRY_NAME, OEHR_COUNTRIES.COUNTRY_ID,
COUNT(OEHR_LOCATIONS.COUNTRY_ID) AS LCOUNT
FROM OEHR_COUNTRIES
LEFT OUTER JOIN OEHR_LOCATIONS
ON OEHR_COUNTRIES.COUNTRY_ID = OEHR_LOCATIONS.COUNTRY_ID
GROUP BY OEHR_COUNTRIES.COUNTRY_NAME, OEHR_COUNTRIES.COUNTRY_ID
ORDER BY LCOUNT;
I've added the missing group-by clause too. With your sample data that gets:
COUNTRY_NAME CO LCOUNT
------------------------ -- ----------
Belgium BE 0
Argentina AR 0
Zimbabwe ZW 0
...
Zambia ZM 0
Mexico MX 1
China CN 1
...
Germany DE 1
Switzerland CH 2
Canada CA 2
Japan JP 2
Italy IT 2
United Kingdom UK 3
United States of America US 4
25 rows selected.
Without adding that missing word, changing the other references to the table to use the (wrong) OUTER alias instead would have meant it would execute, again with the group-by clause added:
SELECT OUTER.COUNTRY_NAME, OUTER.COUNTRY_ID, COUNT(OEHR_LOCATIONS.COUNTRY_ID) AS LCOUNT
FROM OEHR_COUNTRIES
OUTER JOIN OEHR_LOCATIONS
ON OUTER.COUNTRY_ID = OEHR_LOCATIONS.COUNTRY_ID
GROUP BY OUTER.COUNTRY_NAME, OUTER.COUNTRY_ID
ORDER BY LCOUNT;
but it wouldn't have done quite what you wanted - assuming you want to see zero counts for countries with no locations - since it's now an inner join:
COUNTRY_NAME CO LCOUNT
------------------------ -- ----------
Netherlands NL 1
India IN 1
...
Australia AU 1
Switzerland CH 2
Japan JP 2
Canada CA 2
Italy IT 2
United Kingdom UK 3
United States of America US 4
14 rows selected.
The 11 countries with no locations aren't shown at all with an inner join.

Joining a Table with Itself with multiple WHERE statemetns

Long time reader, first time poster.
I'm trying to consolidate a table I have to the rate of sold goods getting lost in transit. In this table, we have four kinds of products, three countries of origin, three transit countries (where the goods are first shipped to before being passed to customers) and three destination countries. The table is as follows.
Status Product Count Origin Transit Destination
--------------------------------------------------------------------
Delivered Shoes 100 Germany France USA
Delivered Books 50 Germany France USA
Delivered Jackets 75 Germany France USA
Delivered DVDS 30 Germany France USA
Not Delivered Shoes 7 Germany France USA
Not Delivered Books 3 Germany France USA
Not Delivered Jackets 5 Germany France USA
Not Delivered DVDS 1 Germany France USA
Delivered Shoes 300 Poland Netherlands Canada
Delivered Books 80 Poland Netherlands Canada
Delivered Jackets 25 Poland Netherlands Canada
Delivered DVDS 90 Poland Netherlands Canada
Not Delivered Shoes 17 Poland Netherlands Canada
Not Delivered Books 13 Poland Netherlands Canada
Not Delivered Jackets 1 Poland Netherlands Canada
Delivered Shoes 250 Spain Ireland UK
Delivered Books 20 Spain Ireland UK
Delivered Jackets 150 Spain Ireland UK
Delivered DVDS 60 Spain Ireland UK
Not Delivered Shoes 19 Spain Ireland UK
Not Delivered Books 8 Spain Ireland UK
Not Delivered Jackets 8 Spain Ireland UK
Not Delivered DVDS 10 Spain Ireland UK
I would like to create a new table that shows the count of goods delivered and not delivered in one row, like this.
Product Delivered Not_Delivered Origin Transit Destination
Shoes 100 7 Germany France USA
Books 50 3 Germany France USA
Jackets 75 5 Germany France USA
DVDS 30 1 Germany France USA
Shoes 300 17 Poland Netherlands Canada
Books 80 13 Poland Netherlands Canada
Jackets 25 1 Poland Netherlands Canada
DVDS 90 0 Poland Netherlands Canada
Shoes 250 19 Spain Ireland UK
Books 20 8 Spain Ireland UK
Jackets 150 8 Spain Ireland UK
DVDS 60 10 Spain Ireland UK
I've had a look at some other posts and so far I haven't found exactly what I'm looking for. Perhaps the issue here is that there will be multiple WHERE statements in the code to ensure that I don't group all shoes together, ore all country groups.
Is this possible with SQL?
Something like this?
select
product
,sum(case when status = 'Delivered' then count else 0 end) as delivered
,sum(case when status = 'Not Delivered' then count else 0 end) as not_delivered
,origin
,transit
,destination
from table
group by
product
,origin
,transit
,destination
This is rather easy; instead of one line per Product, Origin, Transit, Destination and Status, you want one result line per Product, Origin, Transit and Destination only. So group by these four columns and aggregate conditionally:
select
product, origin, transit, destination,
sum(case when status = 'Delivered' then "count" else 0 end) as delivered,
sum(case when status = 'Not Delivered' then "count" else 0 end) as not_delivered
from mytable
group by product, origin, transit, destination;
BTW: It is not a good idea to use a keyword for a column name. I used double quotes to use your column count, which is standard SQL, but I don't know if it works in Google BigQuery. Maybe it must be "Count" rather than "count" or something entirely else.)
SELECT
product, origin, transit, destination,
SUM([count] * (status = 'Delivered')) AS delivered,
SUM([count] * (status = 'Not Delivered')) AS not_delivered
FROM mytable
GROUP BY 1, 2, 3, 4

Same-table Tree Table Query in SQL Server

I've searched but found nothing that could help.
I have the following table in a SQL Server 2005 database:
Parent Child Value
---- -------- ---------
America Mexico 8
America Canada 1
Asia Japan 5
Asia Korea 7
Europe Spain 0
Europe Italy 2
Africa Zimbabwe 1
Mexico Baja California 0
America USA 3
USA California 1
USA Texas 2
Parent and Child are Primary Key, value is not important (IMO). I would like to create a view that results in something like this:
Parent Child Value
---- -------- ---------
America USA 3
USA California 1
USA Texas 2
I would search for America, and the result will give back every nested child there is, recursively, no matter how many it has, since I could include cities, localities, etc.
What I need is similar to what some call a BOM explosion.
Here is how you can do it:
with cte as (
select parent, child
from t
union all
select cte.parent, t.child
from cte join
t
on cte.child = t.parent
)
select cte.*
from cte
where parent = 'America';
Here is a small SQL Fiddle example.