Selecting id against each field in a table - mysql

I have a list of ids as (1,2,3...)
i called it $category_ids. Now in the same table there is a field of super_parent_category which means the highest label of that category in list.
Now i want to retrieve super parent ids for each of the category ids.
SELECT es_super_parent,es_id
FROM ephpb2b_categories
WHERE es_id IN ({$category_ids})");
The above query is returning me only 4 records as all of the ids in $category_ids belongs to these 4 categories.
But i want a result of all 50 records that are in $category_ids.
So if i am supplying 1,2,4,5,6,6,76,
I should return 1,3,4,5,6,66,2,
Thanks

It works for me. Double check your PHP variable $category_ids with a var_dump(), i.e.
I testet it with your provided sample data.
SELECT es_super_parent, es_id
FROM ephpb2b_categories
WHERE es_id IN (1, 2, 4, 5, 6, 6, 76);
and the following table schema:
CREATE TABLE ephpb2b_categories (
es_id INT PRIMARY KEY,
es_super_parent INT NOT NULL,
FOREIGN KEY (es_super_parent) REFERENCES ephpb2b_categories (es_id)
) ENGINE=InnoDB;
And inserted some data:
INSERT INTO ephpb2b_categories (es_id, es_super_parent) VALUES
(0, 0),
(1, 1),
(76, 76),
(2, 76),
(3, 2),
(4, 4),
(5, 5),
(6, 6),
(66, 6);
Here's a working SQL Fiddle

Related

how to find date difference from two different table in mys

I have two tables
1)LEAD TABLE (which have 3 columns)
Lead_ID || Created_Date || Industry
2)ACCOUNTS TABLE (which have 4 columns)
Account_ID||Created_Date|| Revenue_Range|| Lead_ID
How would I get the average number of days between a lead created and an account created
Don't pay attention to mess in data, I just randomly populated it.
Query returns leadId and difference in days between lead.created_date and account.created_date.
Query:
create table Leads
(
leadId int not null,
created_date datetime,
industry varchar(10),
PRIMARY KEY (leadId)
);
create table Accounts
(
accountId int not null,
created_date datetime,
revenue_range varchar(10),
leadId int not null,
FOREIGN KEY (leadId) REFERENCES Leads(leadId)
);
insert into Leads
values
(1, '2020-01-01', 'a'),
(2, '2020-01-02', 'b'),
(3, '2020-01-03', 'c'),
(4, '2020-02-01', 'd'),
(5, '2020-03-01', 'e');
insert into Accounts
values
(1, '2020-01-03', '1k', 1),
(2, '2020-03-10', '2k', 5),
(3, '2020-02-03', '3k', 2);
select
-- l.leadId,
-- l.created_date as LeadCreatedDate,
-- a.created_date as AccountCreatedDate,
-- ABS is used because it returns with minus sign
AVG(ABS(DATEDIFF(l.created_date, a.created_date))) as AvgDifferenceInDaysBetweenCreation
from Leads as l
inner join Accounts as a
on l.leadId = a.leadId;
You can try it out at SQLize Online

Query that join two tables, shows all rows from first table and from second only the row that has the date bigger than today and closer to today

I have two tables, partners and tasks. I would like to write a query that shows all the partners and if there are tasks show only one >= than today (date). It is important that the task is the immediately next to today as date, not the first >= than today that is in the db.
Please find the tables and code below. My problem is that the query does not return the immediately next value to the inserted date, but returns the >= that find in the database.
-- create a table
CREATE TABLE partners
(
id INTEGER PRIMARY KEY,
code INTEGER,
name TEXT
);
CREATE TABLE tasks
(
id INTEGER PRIMARY KEY,
code INTEGER,
comment TEXT,
data INTEGER
);
-- insert some values
INSERT INTO partners VALUES (1, 222, 'M');
INSERT INTO partners VALUES (2, 333, 'F');
INSERT INTO partners VALUES (3, 555, 'F-m');
INSERT INTO tasks VALUES (1, 333, 'f', 2020 );
INSERT INTO tasks VALUES (2, 333, 'f', 2022 );
INSERT INTO tasks VALUES (3, 333, 'f', 2021 );
INSERT INTO tasks VALUES (4, 333, 'f-i', 2023 );
INSERT INTO tasks VALUES (5, 222, 'm', 2021 );
INSERT INTO tasks VALUES (6, 444, 'F', 2025 );
-- fetch some values
SELECT *
FROM partners
LEFT JOIN tasks ON partners.code = tasks.code
WHERE tasks.data >= '2021'
GROUP BY tasks.code
ORDER BY tasks.data ASC;
Desired Result / Query Output:
1 , 222, M, m, 2021
2 , 333, F, f, 2021
3 , 555, F-m, No Task

INSERT INTO... VALUES with inexisting values [duplicate]

This question already has answers here:
MySQL - ignore insert error: duplicate entry
(5 answers)
Closed 4 years ago.
I have a question about insert data in a table.
My table is just composed of a primary key (that is composed by two foreign key).
The problem is: I don't know how to execute my script to insert all rows except non-existing values. Because in the script, some of the inserts are not available anymore.
For some reason, someone gave me the insert script but with some foreign key that were delete. So when I executed the script, I get an error "Constraint fail..." and it's normal.
But how to insert rows easily to avoid error due to invalid foreign key?
INSERT INTO `X_Y` (`x_id`, `y_id`) VALUES
(4, 1),
(4, 2),
(4, 3),
(4, 4),
(4, 5),
(5, 6),
(5, 7),
(5, 8),
(6, 9),
(6, 10),
(7, 11),
(8, 12),
(8, 13),
(11, 18),
(12, 19),
... ( about 2000 insert)
(1680, 2071);
For example : insert (4,1) can't be executed because foreign key x_id 4 does not exist anymore.
Try first inserting your data into a temporary table, with no constraints:
INSERT INTO temp (x_id, y_id)
VALUES
(4, 1),
(4, 2),
...;
Then, use the following query to insert into your target table:
INSERT INTO X_Y (x_id, y_id)
SELECT x_id, y_id
FROM temp t
WHERE
EXISTS (SELECT 1 FROM X x WHERE x.id = t.x_id) AND
EXISTS (SELECT 1 FROM Y y WHERE y.id = t.y_id);
The above insert checks, for every row, that the specified x_id and y_id values in fact have matching primary keys in the two parent tables.

Iterate over a table and perform logic based on a value in MySQL

I'm using a stored procedure for this, and obviously below isn't going to be my exact code, but an highly trimmed version to get the idea across. Please keep in mind that I actually have a lot of filtering done on this temporary table, so adding anything to the CREATE TABLE query would just be more of a hassle than anything.
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS filtered_results AS (SELECT * FROM users);
# Numerous filters removing stuff from the table.
END
For the purpose of this question, lets say that the tables structure is really simple, like so:
user_id INT(11) AUTO_INCREMENT PRIMARY
name VARCHAR(30) NOT NULL
Now let's say that I have a question table with the following structure:
question_id INT(11) AUTO_INCREMENT PRIMARY
user_id INT(11)
text VARCHAR(40)
Now lets say I want to iterate over the table and check some other tables to filter the users that don't have at least 4 questions. So something like this:
for each row in filtered_results
if count(question_id) < 4 where user_id = row.user_id in questions
delete row
end if
end loop
After some discussion and your last comment, I think I came up with a solution more elegant than running a cursor (as I previous mentioned in the comments).
You need to run a delete command into the results based on a LEFT JOIN of your to_be_deleted_table with your questions table. I'm taking into account that your to_be_deleted_table has the user_id on it.
Consider this sample:
create table filtered_results (
user_id integer,
name varchar(10)
);
insert into filtered_results values
(1, 'Bob'), (2, 'Sally'), (3, 'Cheer'), (4, 'Sid'), (5, 'Simon'),
(6, 'Lua'), (7, 'Liv'), (8, 'Taylor'), (9, 'Jay'), (10, 'Mike');
create table questions (
question_id integer,
user_id integer
);
insert into questions values
(1, 1), (2, 1), (3, 1), (4, 1), (5, 1),
(6, 2), (7, 2),
(8, 3), (9, 3), (10, 3), (11, 3),
(12, 4), (13, 4), (14, 4), (15, 4),
(16, 5), (17, 5), (18, 5), (19, 5),
(20, 6), (21, 6), (22, 6), (23, 6),
(24, 7), (24, 7), (24, 7), (24, 7);
This sample has all what you said, users that have 4 (or more questions), users that have less than 4 questions and users that don't have questions at all.
The query to delete the users where they don't have at least 4 question will be:
delete
from filtered_results
where user_id in
(select user_id
from (select f.user_id
from filtered_results f
LEFT JOIN questions q ON (f.user_id = q.user_id)
group by f.user_id
having count(*) < 4) a
);
You must be wondering why I have two subselects, that is because you need to trick the compiler so you can delete the rows from the same table you are doing the select, in this example filtered_results.
If you want to delete from another table based on the user_id at the filtered table just do as follow:
delete
from users
where user_id in
(select f.user_id
from filtered_results f
LEFT JOIN questions q ON (f.user_id = q.user_id)
group by f.user_id
having count(*) < 4
);
Remember that if that is the case you don't need to create the filtered_results just use the query that you create it as a subquery in the first case I showed.
Hope it helps.
And if you want to see it working, take a look at this SQLFiddle

Insert into when number of columns don't match number of values

I have an insert sql statement, e.g.
INSERT INTO `table_a` (`col_a`, `col_b`, `col_c`, `col_d`) VALUES
(1, 2, 3, 4),
(2, 1, 6, 9),
(3, 1, 4, 5)
I want to insert this into another table, however the table I want to insert it into has a different structure to that of the sql statement (it has fewer fields) e.g.
table_b has columns 'col_a', 'col_b', 'col_d'
What do I have to do to the original sql statment so that I can get it to insert it into table_b. I guess it would be something along the lines of just ignoring the value which is in col_c and just sending this to a temp variable rather than a field.e.g.
INSERT INTO `table_b` (`col_a`, `col_b`, #temp_var, `col_d`) VALUES
(1, 2, 3, 4),
(2, 1, 6, 9),
(3, 1, 4, 5)
Use a temporary table:
CREATE TEMPORARY TABLE myTemp (
col_a integer,
col_b integer,
col_c integer,
col_d integer
);
INSERT INTO myTemp (col_a, col_b, col_c, col_d) VALUES (1, 2, 3, 4), (2, 1, 6, 9), (3, 1, 4, 5);
INSERT INTO table_a (SELECT col_a,col_b,col_d FROM myTemp);
The table gets dropped once your session ends (or you can remove it manually)
How about you remove it?
INSERT INTO table_b (col_a, col_b, col_d) VALUES (1, 2, 4), (2, 1, 9), (3, 1, 5)
This is ugly, and I have just tried in in SQLite, but I can image that it also works in MySQL (the documentation doesn't say it's not allowed) (update: see John's comment, it does not work in MySQL):
sqlite> create table t(a,b,c);
sqlite> insert into t (a,b,b,c) values (1,2,3,4);
sqlite> select * from t;
1|2|4