I have the following data structure:
a table entries with a column entry_id
a table data_int with columns entry_id, question and data
a table data_text with columns entry_id, question and data
a table questions with columns question_id
Now I would like to make a MySQL query that does the following: for a given entry_id (say 222) it should select all question_id q from that table for which there is no row with (entry_id=222 AND question_id=q) in data_int, and also no such row in data_text. Is this possible in a single query, and if so how should I do this?
A sample data set would be
entries:
1
2
data_int:
1, 1, 4
1, 2, 56
1, 6, 43
1, 7, -1
data_text:
1, 3, 'hello'
1, 5, 'world'
questions:
1
2
3
4
5
6
7
8
9
10
Then for entry_id=1, the return value should be 4, 8, 9, 10, since these don't appear in either data_ table for entry_id=1.
For entry_id=2, the return value should be 1,2,3,4,5,6,7,8,9,10 since nothing appears in any of the data_ tables.
There are a couple ways to do this. The more efficient way with mysql is probably using multiple outer join / null checks.
select q.*
from questions q
left join data_int di on q.questionid = di.questionid and di.entryid = 1
left join data_text dt on q.questionid = dt.questionid and dt.entryid = 1
where di.entryid is null and dt.entryid is null
Related
I am trying to get information from table_a and auto apply to table_b while increasing pointsA by 5 pointsB by 8 and pointsC by 10
Basically looking for a single script that takes the IDs from table_a ONLY in category 1 while selecting UNIQUE numbers in PlayerAmmount (like for example if 2 (or more) ID's in Category 1 have a PlayerAmmount of 555 it only lists the first one (aka ID 5 in this example) then ignores the rest after it sorts that it gets the ID from those similar then gets other IDs from that same category but with different PlayerAmmounts.
After it does all that and have a list of a few IDs (for example 5, 77, 553, 23523, 53223) it then takes those ID's and places them in table_b with unique entry's incrimented by 1 (like normal counting) and puts those id's into its own entry (like 1 is ID 5 from table_a) and then it takes the base numbers 5 8 10 and adds itself.
So for example row 1:
entry = 1 ID = 5 pointsA = 5, pointsB = 8, and pointsC = 10
then row 2 MUST be adding itself like here:
entry = 2 ID = 77, pointsA = 10, pointsB = 16, pointsC = 20
then row 3 is this:
entry = 3, ID = 553, pointsA = 15, pointsB = 24, pointsC = 30
and so forth as all the IDs from table_a are input into table_b
So far my only attempts to anything in this is the following of different styles but this is all I can come up with. Anyone got a better working way that could work?
INSERT INTO table_b
(entry, ID, pointsA, pointsB, pointsC)
VALUES
((SELECT max(entry) FROM table_b C) + 1,
(SELECT max(ID) FROM table_a in(SELECT DISTINCT PlayerAmmount FROM table_a WHERE Category=1)),
(SELECT max(pointsA) FROM table_b C) + 5,
(SELECT max(pointsB) FROM table_b C) + 8,
(SELECT max(pointsC) FROM table_b C) + 10;
Images:
Table_A
Table_B
Setup
I have a MySQL DB that defines series of numbers within sets as such:
set item1 item2
1 1 2
1 2 3
1 3 4
1 4 5
1 5 6
I want to write a query (or queries) that returns to me the fact that set 1 is a series of numbers that spans from 1 to 6. Is this possible?
Please note that the real DB I'm dealing with contains hundreds of sets and that each set can contain a series of items that can be somewhat long as well (up to 50 items per set, I'm guessing). Also, I'm not totally sure, but the DB might also have cases where the series of numbers split. Using the example above, there may be instances like the following:
set item1 item2
1 1 2
1 2 3
1 3 4
1 4 5
1 5 6
1 3 7
1 7 8
1 8 9
In which case, I'd want to know that set 1 has two series of numbers: [1, 2, 3, 4, 5, 6] and [1, 2, 3, 7, 8, 9]. Is this possible with hopefully one query (or if necessary, multiple queries)?
Edit: Please note that I used the numbers 1-9 in sequential order to make the question easier to understand. The real data is much more mixed up and not that orderly.
As you are aware, MySQL cannot handle recursion 'out-of-the-box', so options include:
writing a stored procedure
switching from an adjacency list to an alternative model (e.g. nested set)
joining the table to itself as often as could be required
handling the recursion in application level code (e.g. a bit of PHP)
Here is an example using option 3, but it could be easily adapted to suit option 4...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(
family_id INT NOT NULL,
item_id INT NOT NULL,
parent_id INT NULL,
PRIMARY KEY(family_id, item_id)
);
INSERT INTO my_table
VALUES (101, 1, null), (101, 2, 1), (101, 3, 2), (101, 4, 3),
(101, 5, 4), (101, 6, 5), (101, 7, 3), (101, 8, 7), (101, 9, 8);
SELECT CONCAT_WS(','
, a.item_id
, b.item_id
, c.item_id
, d.item_id
, e.item_id
, f.item_id
, g.item_id
, h.item_id
, i.item_id
) series
FROM
my_table a
LEFT JOIN
my_table b ON b.parent_id = a.item_id AND b.family_id = a.family_id
LEFT JOIN
my_table c ON c.parent_id = b.item_id AND c.family_id = b.family_id
LEFT JOIN
my_table d ON d.parent_id = c.item_id AND d.family_id = c.family_id
LEFT JOIN
my_table e ON e.parent_id = d.item_id AND e.family_id = d.family_id
LEFT JOIN
my_table f ON f.parent_id = e.item_id AND f.family_id = e.family_id
LEFT JOIN
my_table g ON g.parent_id = f.item_id AND g.family_id = f.family_id
LEFT JOIN
my_table h ON h.parent_id = g.item_id AND h.family_id = g.family_id
LEFT JOIN
my_table i ON i.parent_id = h.item_id AND i.family_id = h.family_id
WHERE
a.parent_id IS NULL;
+-------------+
| series |
+-------------+
| 1,2,3,4,5,6 |
| 1,2,3,7,8,9 |
+-------------+
I can solve the first problem.
Note that "set" is a keyword, so I renamed the first column to "sset"
You can see the result in http://sqlfiddle.com/#!9/ef6360/5
Create table and insert data:
create table test
(
sset int not null
, item1 int not null
, item2 int not null
) engine=InnoDB;
insert into test
values
(1, 1, 2)
, (1, 2, 3)
, (1, 3, 4)
, (1, 4, 5)
, (1, 5, 6)
Run the query:
select
sset
, group_concat(distinct item1or2 order by item1or2 asc)
from
(
select
sset
, item1 as item1or2
from test
union all
select
sset
, item2 as item1or2
from test
) u;
The output is:
1,2,3,4,5,6
I have a list of ids pre-generated that I need to check if exist in a table. My table has two columns, id, name, where id is an auto increment integer and name is a varchar(255).
I basically want to get a count of how many ids do not exist in table foo from my pre-generated list. So say my list has the numbers 5 and 10 in it, what's the best way to write something to the extent of:
select count(*) from foo where id does not exist in ( 5, 10 )
The idea here is that if 5 and 10 do not exist, I need the response 2, and not the number of rows in foo that do not have the id 5 or 10.
TL; DR sample data and queries at rextester
The idea here is that if 5 and 10 do not exist, I need the response 2, and not the number of rows in foo that do not have the id 5 or 10.
You should have provided a little more information to avoid confusion.
Example
id | name
1 | tom
2 | joe
3 | mae
4 | goku
5 | vegeta
If your list contains (1, 2, 3) then your answer should be 0 (since all three are in the table )
If your list contains (1, 2, 6) then your answer should be 1. ( since 1 and 2 are in the table but 6 is in't )
If your list contains (1, 6, 7) then your answer should be 2.
If your list contains (6, 7, 8) then your answer should be 3.
assuming this was your question
If you know the length of your list
select 2 - count(*) as my_count from foo where id in (5, 10)
The following query tells you how many are present in foo.
select count(*) from foo where id in (5,10)
So if you want to find those that do not exist, subtract this result from the length of your list.
select n - count(*) as my_count from foo where id in (5, 10,....)
You could use on fly table using union and the a left join
select count(*)
from my_table as m
left join (
select 5 as id from dual
union
select 10 from dual ) t on t.id = m.id
where t.id is null
otherwise you can populate a tempo table with the value you need and use left join
where the value is null
I wish to port some R code to Hadoop to be used with Impala or Hive with a SQL-like query. The code I have is based on this question:
R data table: compare row value to group values, with condition
I wish to find, for each row, the number of rows with the same id in subgroup 1 with cheaper price.
Let's say I have the following data:
CREATE TABLE project
(
id int,
price int,
subgroup int
);
INSERT INTO project(id,price,subgroup)
VALUES
(1, 10, 1),
(1, 10, 1),
(1, 12, 1),
(1, 15, 1),
(1, 8, 2),
(1, 11, 2),
(2, 9, 1),
(2, 12, 1),
(2, 14, 2),
(2, 18, 2);
Here is the output I would like to have (with the new column cheaper):
id price subgroup cheaper
1 10 1 0 ( because no row is cheaper in id 1 subgroup 1)
1 10 1 0 ( because no row is cheaper in id 1 subgroup 1)
1 12 1 2 ( rows 1 and 2 are cheaper)
1 15 1 3
1 8 2 0 (nobody is cheaper in id 1 and subgroup 1)
1 11 2 2
2 9 1 0
2 12 1 1
2 14 2 2
2 18 2 2
Note that I always want to compare rows to the ones in subgroup 1, even when the rows are themselves in subgroup 2.
You can join the table with itself, using a LEFT JOIN:
SELECT
p.id,
p.price,
p.subgroup,
COUNT(p2.id)
FROM
project p LEFT JOIN project p2
ON p.id=p2.id AND p2.subgroup=1 AND p.price>p2.price
GROUP BY
p.id,
p.price,
p.subgroup
ORDER BY
p.id, p.subgroup
count(p2.id) will count all rows where the join does succeed (and it succeeds where there are cheaper prices for the same id and for the subgroup 1).
The only problem is that you are expecting those two rows:
1 10 1 0
1 10 1 0
but my query will only return one, because I'm grouping by id, price, and subgroup. If you have another unique ID in your project table you could also group by that ID. Please see a fiddle here.
Or you could use an inline query:
SELECT
p.id,
p.price,
p.subgroup,
(SELECT COUNT(*)
FROM project p2
WHERE p2.id=p.id AND p2.subgroup=1 AND p2.price<p.price) AS n
FROM
project p
I have 2 tables:
event_categories containing:
event_category_id, event_category
Sample data:
1, Tennis
2, Volleyball
3, Boxing
4, Skating
Then I have a table that joins users that might possibly be linked to any of these categories.
users_event_categories containing
user_id, event_category_id
Sample data:
1223, 2
1223, 4
5998, 2
I need a query that returns ALL event categories, and returns if a user has that category linked.
So if I query with the user_id 1223 my result would be:
1, Tennis, 0
2, Volleyball, 1
3, Boxing, 0
4, Skating, 1
Or a query with user_id 4444 would return:
1, Tennis, 0
2, Volleyball, 0
3, Boxing, 0
4, Skating, 0
This would work if you only want data about one particular user
select ec.event_category_id, ec.event_category, if(uec.user_id is null, 0, 1)
from event_categories ec
left join users_event_categories uec
on uec.event_category_id = ec.event_category_id and uec.user_id = 1223
select tn2.user_id,event_category,count(event_category) as total from table_name1 tn1
inner join table_name2 tn2 on tn1.event_category_id = tn2.event_category_id
where tn2.user_id = 4444
group by event_category