MySQL: Get results given a condition - mysql

I have a table that looks like this:
target_id || country_code
5-----------||-------US----
5-----------||-------CA---
2----------||-------FR----
3----------||-------SP----
3----------||-------FR----
And another table that looks like this:
target_id || region_name
5-----------||---North America
2-----------||-----France------
3-----------||-----Some Europe
As you can see, table 2 contains locations and target_ids, while table 1 contains where these locations are targeted. In the case of North America, it is targeted to 5, which belongs to Canada and US. France, on the other hand has a target_id of 2, and Some Europe a target_id of 3, which contains France again and Spain.
What I would like to do via MySQL, is to get a table of target_id, country_code, country_name but only for countries. This means, only to the target_ids of table 1 that are in only one row (for example, we know that FR is a country because number 2 is only in FR, and we know that 3 represents a region because it has both Spain and France associated). Is this possible to do via MySQL or will I need two queries and PHP in the middle?
Thanks!

SELECT t1.target_id, t1.country_code, t2.region_name
FROM table1 t1
JOIN table t2
ON t1.target_id = t2.target_id
WHERE (SELECT COUNT(*) FROM table1 t3 WHERE t3.target_id = t1.target_id) = 1
table1 is the one with the country codes, table2 is the one with the the region names.

Related

How can I know how much years have in SQL tables?

I need to print every city from table which has at least one student in every generation. Table is simple but I don't know how to extract every year from that table, because its string.
indeks | city
1/2018 | London ;
2/2018 | Paris ;
3/2018 | null;
4/2019 | London ;
4/2020 | London;
In this case SQL query needs print London, because every year from table has one student (2018,2019 and 2020). I have no idea how to even start query :}
I'd try something like that:
select city from
(
select
city, count(distinct cast(SUBSTRING(indeks, LOCATE('/', indeks)+1) as unsigned)) as dy
from cities
group by city
) as t
where
dy = (
select
max(cast(SUBSTRING(indeks, LOCATE('/', indeks)+1) as unsigned))-min(cast(SUBSTRING(indeks, LOCATE('/', indeks)+1) as unsigned))+1
from cities
)
so in inner query it will calculate how many different years are filled for the each city
outer filter will check which one has all of them

Sisense: Self table join for historical data reporting

Let me start with an example. Suppose I have the following snippet of a slowly changing dimension table containing info about customers:
key id name country valid_from valid_to version
1 abcxyz John Switzerland 2012/01/01 2014/01/01 1
20 abcxyz John Germany 2014/01/01 2017/01/01 2
...
As you can see, every change in a customer's info is recorded as a new entry in the table with the same id, but the version incremented by 1 (key field is primary key of table)
This table is then imported in an Sisense ElastiCube, and then I have access to it from the Dashboard web app.
My question is: How can I create a widget which shows me all customers that moved from country A to country B? (if A were Switzerland and B were Germany, John would show up in the report)
Assuming that (id, version) is unique and that there are no gaps in the version sequence, this query would give you the customers who moved from one country to another.
Please note that it does not give you the most recent version of the customer record, but rather the version of the record when the change occurred. John could be living in Italy in version 3, but the query would still give you the Germany record.
select a.key as moved_from_key
,b.key as moved_to_key
from customers a
join customers b on(
b.id = a.id
and b.version = a.version + 1 -- The version following A
)
where a.country = 'Switzerland'
and b.country = 'Germany';

how to integrate all columns from one table into one column of another table using mysql

table 1: employee
name| mobile| location
alex| 123 | australia
john| 456 | paris
kohl| 678 | australia
table 2:employment
id|location |data
1 |australia|[{"name":"alex","mobile":"123"},{"name":"kohl","mobile":"678"}]
2 |paris |[{"name":"john","mobile":"456"}]
i have two tables named "employee" and "employment". How can i get all the column values of employee table into one column of employment table as shown in table 2. I am new to SQL querying. I honestly don't have any idea on how to proceed. Any pointers and suggestions are appreciated.
You can use the following solution using CONCAT and GROUP_CONCAT to get this result:
SELECT location, CONCAT("[", GROUP_CONCAT(CONCAT('{"name":"', name, '","mobile":"', mobile, '"}')), "]") AS data
FROM employee
GROUP BY location
demo: http://sqlfiddle.com/#!9/ab25ee/2/0
To JOIN the employee table with the employment you can use the following solution:
SELECT employment.id, employment.location, CONCAT("[", GROUP_CONCAT(CONCAT('{"name":"', name, '","mobile":"', mobile, '"}')), "]") AS data
FROM employment INNER JOIN employee ON employment.location = employee.location
GROUP BY id, location
demo: http://sqlfiddle.com/#!9/12f9c9/1/0

mysql query - multilevel locations

I've a table with following structure and values:
location_id, location_name, parent_id
1, USA, 0
2, Illinois, 1
3, Chicago, 2
4, New York, 1
In this fragment, then row with 'USA' would be considered a country, because value of parent_id is 0. But, if parent_id has some other value, then it would signify, that the particular location is under some location. We have multiple levels of location and it is not set. It can be 2 level, 3 level, 4 level, etc.
For ex. USA > Alabama > Alabama Gulf Coast > Gulf Shores
I need to get all location_id entries, which has no further location. So that in above example, I should get answer as "Gulf Shores".
I think the solution should be something like:
SELECT location_id FROM location WHERE "( parent_id does not contain any value from location_id )"
But i cannot figure out the exact syntax. How should I implement this?
Maybe you would be better off, if you used Closure Tables to implement this ( as recommended in "SQL Antipatterns" book).
select location_id from location l
where not exists
(select null
from location
where parent_id = l.location_id);

help with subquery! returns more than 1 row

i dont understand the problem with returning multiple rows:
here is my table BBC:
name region area population gdp
Afghanistan South Asia 652225 26000000
Albania Europe 28728 3200000 6656000000
Algeria Middle East 2400000 32900000 75012000000
Andorra Europe 468 64000
Angola Africa 1250000 14500000 14935000000
etc.............................
question:
List the name and region of countries
in the regions containing 'India',
'Iran'.
this is my statement:
select name from bbc where region = (select region from bbc where name='India' or name='Iran')
it returns:
sql: errorSubquery returns more than 1 row
whats wrong with my statement? the answer should be in the form of a select statement within a select statement
thank you!
This is because you are trying to compare region to a table of values. Instead, try using in:
select name
from bbc
where region in
(select region from bbc where name='India' or name='Iran')
You might have slightly different syntax and it'll work:
SELECT name
FROM bbc
WHERE region IN
(
SELECT region FROM bbc WHERE name='India' OR name='Iran'
)
The only difference being that instead of equals (=), we use IN.
The reason your previous one failed is because to use equals, you compare one value with one other value. What you were accidentally doing is comparing one value with multiple values (the "SubQuery returns more than one row"). The change here is saying where region is within the results returned from the sub query.
select name,region from bbc where region IN (select region from bbc where name IN('India','Iran'))