How to take more than one rows from condition? - mysql

I have 2 different tables. First contains the following columns: id, names and id_of_exec, the other: id_of_exec and name_of_exec. I want to join them, but I'm having a problem with the join condition:
ON (x.id_of_exec = y.id_of_exec AND ( y.name = "XYZ" OR y.name = "ABC"))
(Names - XYZ and ABC have different id_of_exec)
And there is problem because column id_of_exec has the same id_of_exec for more than one id and SQL shows me only y.name = "XYZ". How to get results of both XYZ + ABC. On the end I'm grouping by names because I need to get just names from 1st table where there are names from 2nd table XYZ + ABC.
I tried to use select behind AND but select returns more than 1 row.

ON (x.id_of_exec = y.id_of_exec )
where ( y.name = "XYZ" OR y.name = "ABC")
The above query will join only on id_of_exec and then filter the records based on the values "XYZ" or "ABC" .

Related

INNER JOIN Statement returns multiple rows instead of one

There are two tables, namely sku and country without any matching columns. I need to retrieve a unique field printable_name from country table based on the value of c_code in sku table. c_code column has multiple same country codes(Example: 124) while numcode column in the country table contains the same country code but only once because it is a unique field. The row that has the unique numcode has the country name which I am finally trying to retrieve. The result from my SQL query below gives multiple rows instead of just one from the country table. I just want one record only from country table, which is printable_name
I am trying to combine the following SQLs into one with the JOIN statement.
$vendor_sku = $my_line_item['sku'];
// Build SQL to retrieve country name.
$sql = "SELECT c_code FROM sku WHERE item_sku = '" . $vendor_sku . "'";
$sql = "SELECT printable_name FROM country WHERE numcode = '" . $c_code . "'";
SELECT country.printable_name
FROM country INNER JOIN sku ON country.numcode = sku.c_code
WHERE country.numcode = "124"
Part of my country table is :
part of sku table is:
Country table has only one entry for numcode 124 as seen below.
Try:
SELECT a.printable_name
FROM country a
WHERE
1=1
and a.numcode = '124'
and exists (select 1 from sku s where a.numcode = s.c_code)
I just want the record only from country table
Then why are you using the sku table?
SELECT c.printable_name
FROM country c
WHERE c.numcode = 124;
Note: I assume that 124 is a number, so I removed the quotes. If it is a string, then use a string with single quotes, '124'.

Combining Data in Two Tables SQL

I'm sure a very basic question, but I'm continue to be stuck:
Table A - image_number, camera_type, total_sales
Table B - image_number, keyword
Table A has one ROW for each image_number - example:
image_number="AXJ789, camera_type="Nikon", total_sales=678
image_number="JIJ123", camera_type="Canon", total_sales=999
image_number="KNI908", camera_type="Sony", total_sales=565
Table B has many ROWs for each image_number - example:
image_number="AXJ789", keyword = "rain"
image_number="AXJ789", keyword = "mountain"
image_number="AXJ789", keyword = "grass"
image_number="AXJ789", keyword = "cloud"
What I'm trying to do is JOIN the two tables so that I can generate the following output:
image_number="AXJ789", camera_type=678, camera_type="Nikon", keyword(1) = "rain", keyword(2) = "mountain", keyword(3) = "grass", keyword(4) = "cloud"
In other words, I want to have all items in each ROW in table A + all the items from table B. For each image_number in Table A, there could be no "keywords" in Table B or 50 keywords - depends on the image.
When I do an INNER JOIN, of course I can get one "keyword" from table B, but I can't figure out how to get all of them.
You can concatenate the keywords together:
select a.*,
(select group_concat(b.keyword)
from b
where b.image_number = a. image_number
) as keywords
from a;
This creates a comma-delimited list of the keywords. This is much simpler (in MySQL) than trying to put them in separate columns. In fact, if you wanted separate columns, I might suggest parsing this result:
select a.*, -- or whatever columns you want
substring_index(keywords, ',' 1) as keyword1,
substring_index(substring_index(keywords, ',' 2), ',', -1) as keyword2,
substring_index(substring_index(keywords, ',' 3), ',', -1) as keyword3,
substring_index(substring_index(keywords, ',' 4), ',', -1) as keyword4
from a left join
(select b.image_number, group_concat(b.keyword) as keywords
from b
group by b.image_number
) b
on b.image_number = a. image_number;
You can generate a comma-separated list of keywords for each image using GROUP_CONCAT and JOIN (but use a LEFT JOIN if an image may have no keywords).
SELECT a.*, GROUP_CONCAT(b.keyword) AS keyword_list
FROM a
JOIN b on b.image_number = a.image_number
GROUP BY a.image_number
Output for your sample data:
image_number camera_type total_sales keyword_list
AXJ789 Nikon 678 rain,mountain,grass,cloud
Demo on dbfiddle
You can then parse this into an array in your application, for example in PHP (if you have read the row into $row):
$keywords = explode(',', $row['keyword_list']);
print_r($keywords);
Output:
Array
(
[0] => rain
[1] => mountain
[2] => grass
[3] => cloud
)

Join 3 Tables Doesn't Return Correct Result

I have three tables and their structure are below.
In keyword table I have unique keywords. A keyword has more than one user or domain_id so I have keyword_user table.
In rank table I have some numbers related to keywords.
I want to return all keywords related with my selected domain_id.
My conditions are:
Must: return min(rank_position) from rank table
Must: rank.rank_date = keyword.keyword_last_date
Problem is:
If I write keyword_user.domain_id = 1234 it returns all rows from keyword table but rank results are incorrect.
If I write rank.domain_id it returns only rows that related with keyword_last_date normally.
using min(rank_position) on SELECT causing wrong results.
I want all keywords from keyword table where keyword_user.domain_id = XXX and rank_date = keyword.keyword_last_date. Domain must my domain id not anything else.
SELECT rank.rank_id
, keyword_name
, keyword_last_date
, MIN(rank_position) my_rank
, rank_url
, rank.domain_id
FROM keyword
LEFT
JOIN keyword_user
ON keyword.keyword_id = keyword_user.keyword_id
LEFT
JOIN rank
ON keyword.keyword_id = rank.keyword_id
WHERE keyword_user.domain_id = 8262
AND rank.domain_id = 8262
AND rank_date = keyword.keyword_last_date
GROUP
BY keyword.keyword_name
ORDER
BY rakip_rank
As you can see from picture. domain_id column has different values but I have domain_id = 8262. They are not related to my expected result. Also my_rank column should different values not only "1".
TABLE: keyword
TABLE: rank
TABLE: keyword_user

Count with a subselect yielding double the amount

I'm new to SQL.
Problem: Say if I were to count the amount that is contained in the alias table of "x" COUNT(x.xValue) to be 217. Now when I add the sub-query "y" and then do the count again, I have the COUNT(x.xValue) to suddenly square its self -> 47089. Why is this happening?
(Note: Both alias tables "x" and "y" have the same amount -> 217.)
How do I fix this problem. I don't want to use Variables or Views.
SELECT COUNT(x.xValue) + COUNT(y.yValue) AS CountXY
FROM
(SELECT value AS xValue FROM table1
WHERE
...) AS x,
(SELECT value AS yValue FROM table1
WHERE
...) AS y
Result of 'CountXY' : 94178.
Result I'm expecting 'CountXY' : 434
The problem is that you are doing two sub-queries and then trying to call the values return directly.
This will behave as selecting one value from table x and matching it to every single value in table y. This obviously creates the squared return effect.
What you need to use is the JOIN to combine both data-sets so that you get the 1 to 1 relationship you are trying to achieve.
This is how the above should be done with your previous sub-query:
SELECT COUNT(A.value) AS x, COUNT(B.value) AS y
FROM table1 AS A
JOIN table1 AS B
ON A.attr1 = B.attr1
AND A.attr2 = B.attr2
WHERE B.attr1 != 'whatever'
AND B.attr2 = 'whatever'
AND A.attr3 = 'something'
AND B.attr3 = 'something different'
The above query should return the correct 1 to 1 relationship you are looking for. Replacing your sub-query with the one above should give you the correct answer

Why am i getting "Subquery returns more than 1 row"

Hi I am making a webrowser game and I am trying to get monsters into my data base when I get the error:
Subquery returns more then 1 row
here is my code
INSERT INTO monster_stats(monster_id,stat_id,value)
VALUES
( (SELECT id FROM monsters WHERE name = 'Necroborg!'),
(SELECT id FROM stats WHERE short_name = 'atk'),
2);
any ideas how to fix this problem?
Try use LIMIT 1
INSERT INTO monster_stats(monster_id,stat_id,value) VALUES ((SELECT id FROM monsters WHERE name = 'Necroborg!' LIMIT 1),(SELECT id FROM stats WHERE short_name = 'atk' LIMIT 1),2);
Or you could use Insert from select, with join, if you have relations with 2 tables.
INSERT INTO monster_stats(monster_id,stat_id,value)
(SELECT monsters.id, stats.id, 2 as value FROM monsters
LEFT JOIN stats on monsters.id = stats.monsters_id
WHERE monsters.name = 'Necroborg!'
AND stats.short_name = 'atk'
)
MYSQL insert from select:
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html
The problem is one or both of the following:
There is more than one monster named 'Necroborg!'.
There is more than on stat named 'atk'.
You need to decide what you want to do. One option (mentioned elsewhere) is to use limit 1 to get only one value from each statement.
A second option is to better specify the where clause so you get only one row from each table.
Another is to insert all combinations. You would do this with insert . . . select and a cross join:
INSERT INTO monster_stats(monster_id, stat_id, value)
SELECT m.id, s.id, 2
FROM (SELECT id FROM monsters WHERE name = 'Necroborg!') m CROSS JOIN
(SELECT id FROM stats WHERE short_name = 'atk');
A third possibility is that there is a field connecting the two tables, such as monster_id. But, based on the names of the tables, I don't think that is true.