MySQL 2 Columns from 2 tables - mysql

There we go actually I think it should be ok but it isn't
SELECT animize_users.username, animize_profile.avatar
FROM animize_users, animize_profile
WHERE `animize_profile.userid` = 1 AND `animize_users.id` = 1
LIMIT 0 , 1
Please don't tell me to put this in a a seperate query each - as i don't want to make needless calls...

Just drop the quotes entirely if they're not required, i.e.
SELECT animize_users.username, animize_profile.avatar FROM animize_users au join animize_profile ap on ap.userid = au.id WHERE au.id = 1
If you've got a proper PK on user id, the user shouldn't repeat and really limit 1 would only effect your selection of profile. I'd suggest adding to the where to ensure you get the most appropriate profile.
Also, if "animize" is your product, don't prefix your tables with it, it's redundant.

Try it this way with backticks correctly used:
SELECT animize_users.username, animize_profile.avatar
FROM animize_users, animize_profile
WHERE `animize_profile`.`userid` = 1 AND `animize_users`.`id` = 1
LIMIT 0 , 1

Related

MySQL joined WHERE IN combined with NOT IN (categories)

I have a whitelist and a blacklist of category UIDs.
I am trying to tell MySQL that
i want all pages that have at least "57", but
that i don't want any pages that ALSO have "206".
Usually i would say "IN(57)" excludes everything else, like 206, but certain pages have both (57 and 206) so it's true either way.
The unwanted 206 page is still included.
Here's the Query:
SELECT pages.uid, pages.title
FROM pages
LEFT JOIN sys_category_record_mm AS cats ON (pages.uid = cats.uid_foreign AND cats.tablenames="pages" AND cats.fieldname="categories")
WHERE pages.hidden=0 AND pages.deleted=0
AND cats.uid_local IN (57)
AND cats.uid_local NOT IN (206)
ORDER BY (CASE WHEN pages.starttime > 0 THEN pages.starttime ELSE pages.crdate END) DESC
LIMIT 10
Here is a DB Fiddle for this Problem:
https://www.db-fiddle.com/f/fxGQbBVZHb8aJDJ4eiTUW1/0
I am out of ideas. Any help/hint would be much appreciated
I find this sort of logic simplest with group by and having:
select c.uid_foreign
from sys_category_record_mm c
where c.tablenames = 'pages' AND c.fieldname = 'categories'
group by c.uid_foreign
having sum(c.uid_local in (57)) > 0 and
sum(c.uid_local in (206)) = 0;
You can join back to your pages to get additional information.

MySQL Query with LEFT JOIN where second table has a 2-Part Primary Key

I have 2 tables in a MySQL database (storeskus). The first is FBM_Orders and the second is IM_INV.
I am trying the query
SELECT `FBM_Orders`.`order-id`,`FBM_Orders`.`order-item-id`,`FBM_Orders`.`purchase-date`,
`FBM_Orders`.`promise-date`,`FBM_Orders`.`buyer-name`,`FBM_Orders`.`sku`,
`FBM_Orders`.`product-name`,`FBM_Orders`.`quantity-purchased`,
`FBM_Orders`.`recipient-name`,`IM_INV`.`LOC_ID`,`IM_INV`.`QTY_ON_HND`
FROM `FBM_Orders`
LEFT JOIN `IM_INV` ON `FBM_Orders`.`sku` = `IM_INV`.`ITEM_NO`
WHERE `FBM_Orders`.`quantity-to-ship` > 0
ORDER BY `FBM_Orders`.`purchase-date`, `IM_INV`.`LOC_ID` ASC;
Because the IM_INV table has a 2-part primary key: ITEM_NO & LOC_ID, I am getting 4 lines for each ITEM_NO with the QTY_ON_HND for each of the 4 locations (LOC_ID).
I am fairly new to SQL so I'm thrilled to have gotten this far, but how can I make it so that the result is a single line per ITEM_NO but with a column for each LOC_ID with its QTY_ON_HND?
Example:
My current result is
FBM_Order.sku FBM_Order.quantity-purchased IM_INV.LOC_ID QTY_ON_HND
'SCHO645256' 1 AF 2
'SCHO645256' 1 LO 2
'SCHO645256' 1 S 3
'SCHO645256' 1 SL 1
How can I change that to
FBM_Order.sku FBM_Order.quantity-purchased QTY_ON_HND_AF QTY_ON_HND_LO QTY_ON_HND_S QTY_ON_HND_SL
'SCHO645256' 1 2 2 3 1
?
Thanks!
You may load it as you already do and treat it inside your application, but if you really wanna make that inside your MySQL, try GROUP CONCAT and JSON as follows:
SELECT
GROUP_CONCAT(JSON_OBJECT(
'LOC_ID', IM_INV.LOC_ID,
'QTY_ON_HND', QTY_ON_HND
))
{another fields}
FROM `FBM_Orders`
LEFT JOIN `IM_INV` ON `FBM_Orders`.`sku` = `IM_INV`.`ITEM_NO`
WHERE `FBM_Orders`.`quantity-to-ship` > 0
GROUP BY `FBM_Orders`.`order-id`;
Note: JSON is just available for MySQL 5.7+ and may slow down your query a little bit. You're still gonna need convert your data to array inside your application. So it's half done inside your app and half inside your database.

Do a while in a query, subquery

I want do query that show data of some users bat, first is a other query, is something difficult of explain. i dont want get the data of the users that me follow, i want see data that me don't follow. So i have two table "follow_follower", "user" and now do a middle query but doesn't match:
follow_follower
cod seguidor seguido
1 1 2
2 1 3
3 1 8
4 1 6
5 8 2
6 2 8
7 2 4
8 3 2
9 5 1
User
cod nombre apellido telefono
1 carlos cardenas 12587
2 Umberto Contreras 125488
3 carlos Torres 44587
4 Victor Sambrano 69754
5 Carlos Barragan 3698741
6 Jorge Cantor
7 Umberto Zanetty 578825
8 Miguel Cantor 5488787
ok and if you see are four fields in follow_follower that the user is 1 (Carlos Cardenas), how do query that first get all user that me follow and after select all data of people diferent "DISTICN" see my query:
select distinct(nombre), apellido, telefono
FROM usuario
where cod<> ANY(select seguido from follow_follower where seguidor=1)
order by cod
But only DISTINC a ANY row of all query.
ok i want a list little of people that me don't follow but i see your query and show error, i know little of mysql query ADVANCE :( and the other problem is that my db is write in spanish... but go to try the table db like are!!! :
this is a the true query:
SELECT distinct(usua.cod), usua.nick, desi.usuario, main.dir, main.size, main.x, main.y, main.R, main.G, main.B, main.A
FROM usuario AS usua, design AS desi, mainPhoto AS main
WHERE desi.usuario = usua.cod
AND desi.cod = main.design
AND usua.cod <> ANY(select seguido from seguidor_seguido where seguidor=1)/**!!!!!/
AND main.dir <> ''
AND main.type =1
ORDER BY usua.nick DESC
LIMIT 44 , 6
so the unique table that true import are usuario (content data of user) and seguidor_seguido(content all the records follow)
---describe table seguidor_seguido:
seguidor_seguido
cod // is the id of the record
seguidor // is the user that follow to other users
seguido // is the user that is followed by other users
Although the request is different from the original is the same problem!!!
thanks :D
Sounds like you want a list of all users that don't follow you. I'm not sure if you want that to be transitive or not (i.e., including users that follow users that follow you, etc.).
If you just want to do it one level deep, it'll go like this. You want to get a list of all entries in the follow_follower where the seguido (I assume that's supposed to mean "person who is being followed") is not you. Users can follow other people, but they can't follow you. You can join twice against the User table to get user names.
SELECT DISTINCT
usuario_seguidor.nombre,
usuario_seguidor.applido,
usuario_seguidor.telephono
FROM follow_follower
JOIN usuario AS usuario_seguidor
ON usuario_seguidor.cod = follow_follower.seguidor
WHERE follow_follower.seguido <> 1
I could finally end the query and match ok!! :D see:
SELECT U.cod, U.nombre, U.apellido, U.telefono FROM User U LEFT JOIN (SELECT f.seguido
FROM follow_follower f
WHERE f.seguidor = 1)t1 ON u.cod = t1.seguido
WHERE t1.seguido IS NULL AND U.cod <> 1 GROUP BY U.cod
this is the query that me need, but i thanks :D

Return a boolean value if string matches one of list MYSQL

I have 2 tables
SEQUENCES
-----------------
sequence (blob)
KNOWN_SEQUENCES
-----------------
sequence (blob)
I need to return a list of all entries in the sequences table and Id like to return a boolean if it is in the known table list
sequence known
----------------------------------
111423fa686ca 0
066787caf5671 1
See use of 'CASE' in mysql. http://dev.mysql.com/doc/refman/5.0/en/case-statement.html.
I am posting a sample here. Sorry I dont have access to a sql server right now to test this. Try to see if something like this helps.
Select s.sequence,
CASE
WHEN (select count(*) from KNOWN_SEQUENCES k where k.sequence = s.sequence) > 0 THEN '1'
ESLE '0'
END
`known`,
from SEQUENCES s;
Also, indexing the table 'KNOWN_SEQUENCES' on column 'sequence' might be better keeping performance in mind.
I did get it working, but it takes 3 seconds for only 9,000 records. That may be the best I can do. Luckily I just need to run this once.
SELECT
sequences.*,
1 as `known`
FROM
sequences, known_sequences
WHERE sequences.sequence = known_sequences.sequence
UNION
SELECT
sequences.*,
0 as `known`
FROM
sequences, known_sequences
WHERE sequences.sequence NOT IN(
SELECT known_sequences.sequence
FROM known_sequences) GROUP BY sequences.id
This might be a little long, but it should work.
SELECT
s.*,
1 as `known`
FROM
sequence AS s
INNER JOIN
known_sequences AS ks
ON
s.sequence = ks.sequence
UNION
SELECT
s.sequence,
0 AS `known`
FROM
sequence AS s
WHERE
s.sequence NOT IN
(
SELECT
s2.sequence
FROM
sequence AS s2
LEFT JOIN
known_sequences AS ks
ON
s.sequence == ks.sequence
)

Combine Multiple child rows into one row MYSQL

I have two tables
Ordered_Item
ID | Item_Name
1 | Pizza
2 | Stromboli
Ordered_Options
Ordered_Item_ID | Option_Number | Value
1 43 Pepperoni
1 44 Extra Cheese
2 44 Extra Cheese
What I am looking to output is a mysql query is something to this effect
Output
ID | Item_Name | Option_1 | Option_2
1 Pizza Pepperoni Extra Cheese
2 Stromboli NULL Extra Cheese
I have tried numerous options most ending in syntax error, I have tried group_concat but thats not really what I am looking for. I have a crude example below of what I think might be a start. I need the options to be in the same order every time. And in the program where the info is collected there is no way to reliable ensure that will happen. Is it possible to have them concatenate according to option number. Also I know that I will never have over 5 options so a static solution would work
Select Ordered_Items.ID,
Ordered_Items.Item_Name,
FROM Ordered_Items
JOIN (SELECT Ordered_Options.Value FROM Ordered_Options Where Option_Number = 43) as Option_1
ON Ordered_Options.Ordered_Item_ID = Ordered_Item.ID
JOIN (SELECT Ordered_Options.Value FROM Ordered_Options Where Option_Number = 44) as Option_2
ON Ordered_Options.Ordered_Item_ID = Ordered_Item.ID;
The easiest way would be to make use of the GROUP_CONCAT group function here..
select
ordered_item.id as `Id`,
ordered_item.Item_Name as `ItemName`,
GROUP_CONCAT(Ordered_Options.Value) as `Options`
from
ordered_item,
ordered_options
where
ordered_item.id=ordered_options.ordered_item_id
group by
ordered_item.id
Which would output:
Id ItemName Options
1 Pizza Pepperoni,Extra Cheese
2 Stromboli Extra Cheese
That way you can have as many options as you want without having to modify your query.
Ah, if you see your results getting cropped, you can increase the size limit of GROUP_CONCAT like this:
SET SESSION group_concat_max_len = 8192;
I appreciate the help, I do think I have found a solution if someone would comment on the effectiveness I would appreciate it. Essentially what I did is. I realize it is somewhat static in its implementation but I does what I need it to do (forgive incorrect syntax)
SELECT
ordered_item.id as `Id`,
ordered_item.Item_Name as `ItemName`,
Options1.Value
Options2.Value
FROM ORDERED_ITEMS
LEFT JOIN (Ordered_Options as Options1)
ON (Options1.Ordered_Item.ID = Ordered_Options.Ordered_Item_ID
AND Options1.Option_Number = 43)
LEFT JOIN (Ordered_Options as Options2)
ON (Options2.Ordered_Item.ID = Ordered_Options.Ordered_Item_ID
AND Options2.Option_Number = 44);
If you really need multiple columns in your result, and the amount of options is limited, you can even do this:
select
ordered_item.id as `Id`,
ordered_item.Item_Name as `ItemName`,
if(ordered_options.id=1,Ordered_Options.Value,null) as `Option1`,
if(ordered_options.id=2,Ordered_Options.Value,null) as `Option2`,
if(ordered_options.id=43,Ordered_Options.Value,null) as `Option43`,
if(ordered_options.id=44,Ordered_Options.Value,null) as `Option44`,
GROUP_CONCAT(if(ordered_options.id not in (1,2,43,44),Ordered_Options.Value,null)) as `OtherOptions`
from
ordered_item,
ordered_options
where
ordered_item.id=ordered_options.ordered_item_id
group by
ordered_item.id
If you know you're going to have a limited number of max options then I would try this (example for max of 4 options per order):
Select OI.ID, OI.Item_Name, OO1.Value, OO2.Value, OO3.Value, OO4.Value
FROM Ordered_Items OI
LEFT JOIN Ordered_Options OO1 ON OO1.Ordered_Item_ID = OI.ID
LEFT JOIN Ordered_Options OO2 ON OO2.Ordered_Item_ID = OI.ID AND OO2.ID != OO1.ID
LEFT JOIN Ordered_Options OO3 ON OO3.Ordered_Item_ID = OI.ID AND OO3.ID != OO1.ID AND OO3.ID != OO2.ID
LEFT JOIN Ordered_Options OO4 ON OO4.Ordered_Item_ID = OI.ID AND OO4.ID != OO1.ID AND OO4.ID != OO2.ID AND OO4.ID != OO3.ID
GROUP BY OI.ID, OI.Item_Name
The group by condition gets rid of all of the duplicates that you would otherwise get. I've just implemented something similar on a site I'm working on where I knew I'd always have 1 or 2 matched in my child table, and I wanted to make sure I only had 1 row for each parent item.
What you want is called a pivot, and it's not directly supported in MySQL, check this answer out for the options you've got:
How to pivot a MySQL entity-attribute-value schema
Here is how you would construct your query for this type of requirement.
select ID,Item_Name,max(Flavor) as Flavor,max(Extra_Cheese) as Extra_Cheese
from (select i.*,
case when o.Option_Number=43 then o.value else null end as Flavor,
case when o.Option_Number=44 then o.value else null end as Extra_Cheese
from Ordered_Item i,Ordered_Options o) a
group by ID,Item_Name;
You basically "case out" each column using case when, then select the max() for each of those columns using group by for each intended item.
Joe Edel's answer to himself is actually the right approach to resolve the pivot problem.
Basically the idea is to list out the columns in the base table firstly, and then any number of options.value from the joint option table. Just left join the same option table multiple times in order to get all the options.
What needs to be done by the programming language is to build this query dynamically according to a list of options needs to be queried.