I'm not sure how to word what I need so here goes... This is part of a search that allows a type and a state to be selected. I need to be able to run this query to match the type and state from the same mysql column which is meta_value. The problem is it's returning every type for the selected state in the result.
Example: I pick Drag Strip for the type and South Carolina for the state I only want to see the Drag Strip's in South Carolina and not the other types (oval, road course, etc) that are in South Carolina or any other state.
Below is what I have right now that isn't working, I'm not really sure where to go with it to get the result I need.
SELECT dmp_postmeta.meta_value, dmp_posts.post_title, dmp_posts.post_type,
dmp_posts.post_status, dmp_posts.id
FROM dmp_postmeta, dmp_posts
WHERE dmp_postmeta.meta_value IN ('South Carolina','Drag Strip')
AND dmp_posts.post_type='my_custom_tracks'
AND dmp_posts.post_status='publish'
GROUP BY dmp_postmeta.post_id ORDER BY dmp_posts.post_title
meta_key meta_value
Track_Type Drag Strip
Track_Type Oval
Track_Location South Carolina
Track_Location Texas
******Solved******
"SELECT p.ID as id, p.post_title, p.post_type, p.post_status as post_status, MAX(CASE WHEN pm1.meta_value='".$track_type."' then pm1.meta_value ELSE NULL END) as track_type, MAX(CASE WHEN pm1.meta_value='".$track_state."' then pm1.meta_value ELSE NULL END) as track_state FROM dmp_posts p LEFT JOIN dmp_postmeta pm1 ON ( pm1.post_id = p.ID) WHERE p.post_type='my_custom_tracks' AND p.post_status='publish' GROUP BY p.ID, p.post_title ORDER BY p.post_title"
This is what I finally got to work. Thanks for the help guys.
"SELECT p.ID as id, p.post_title, p.post_type, p.post_status as post_status, MAX(CASE WHEN pm1.meta_value='".$track_type."' then pm1.meta_value ELSE NULL END) as track_type, MAX(CASE WHEN pm1.meta_value='".$track_state."' then pm1.meta_value ELSE NULL END) as track_state FROM dmp_posts p LEFT JOIN dmp_postmeta pm1 ON ( pm1.post_id = p.ID) WHERE p.post_type='my_custom_tracks' AND p.post_status='publish' GROUP BY p.ID, p.post_title ORDER BY p.post_title"
Related
so I have this SQL query:
SELECT
p.ID
FROM
`cdlr_posts` p,
cdlr_postmeta pm
WHERE
pm.post_id=p.ID AND
`post_type` = 'shop_order' AND
pm.meta_key = '_statusCDLR' AND
pm.meta_value <> 1
group by
p.ID
What I need is to show all the IDS if they match with those conditions, but I will also like to show the ones that do not contain the "_statusCDLR" meta_key I tried something like this with no luck:
WHERE
pm.post_id=p.ID AND
`post_type` = 'shop_order' AND
(pm.meta_key = '_statusCDLR' AND pm.meta_value <> 1 OR pm.meta_key <> '_statusCDLR')
group by
Any help will be appreciated to achieve what I need.
I understand that your requirement is to select the id of posts that :
either have a corresponding record in cdlr_post_meta with meta_key = 'statusCDLR' and meta_value <> 1
or do not have a record cdlr_post_meta with meta_key = 'statusCDLR'
A strategy to achieve this is to use a LEFT JOIN to search for a record in cdlr_post_meta with meta_key = 'statusCDLR', and then implement the rest of the logic in the WHERE clause (if there is no corresponding record, the columns of pm are all NULL).
SELECT p.ID
FROM cdlr_posts p
LEFT JOIN cdlr_postmeta pm
ON pm.post_id = p.ID AND pm.meta_key = '_statusCDLR'
WHERE
p.post_type = 'shop_order'
AND ( pm.post_id IS NULL OR pm.meta_value <> 1 )
GROUP BY p.ID
PS - General remarks regarding your sql :
When mixing ORs and ANDs, you need to surround the test expressions within parentheses to avoid running into prescedence issues (AND has higher precedence than OR).
you should use explicit JOINs instead of implicit ones.
I am working on a query to flatten some wp_postsmeta data in a WordPress database and need to set a specific value on various meta_values. I have a key of category and various category values, for each value, I want to set a column named color with a named color for our brand palette
select post_title as title,
MAX(CASE WHEN meta_key='corporate_calendar_category' THEN meta_value END) as 'category',
MAX(CASE WHEN meta_key = 'corporate_calendar_subcategory' THEN meta_value END) as 'subcategory',
// Do I need to include a nested CASE WHEN?
MAX(CASE WHEN meta_key = 'corporate_calendar_subcategory' and meta_value = 'Marketing' THEN 'blueLagoon' END) as 'color',
MAX(CASE WHEN meta_key = 'corporate_calendar_presenter' THEN meta_value END) as 'presenter',
MAX(CASE WHEN meta_key = 'corporate_calendar_date' THEN meta_value END) as 'start_date',
MAX(CASE WHEN meta_key = 'corporate_calendar_time' THEN meta_value END) as 'start_time',
MAX(CASE WHEN meta_key = 'corporate_calendar_duration' THEN meta_value END) as 'duration',
MAX(CASE WHEN meta_key = 'corporate_calendar_registration_link' THEN meta_value END) as 'registration_link',
MAX(CASE WHEN meta_key = 'corporate_calendar_description' THEN meta_value END) as 'description',
MAX(CASE WHEN meta_key = 'corporate_calendar_image_path' THEN meta_value END) as 'image_path'
FROM wp_posts p
JOIN wp_postmeta m ON p.id = m.post_id
where p.post_type = 'calendar-event'
and p.post_status = 'publish'
GROUP BY p.id
corporate_calendar_subcategory has many values, Marketing, HR, Company Holiday, etc, and for each subcategory I want each row to have a specific color.
title category subcategory color presenter start_date etc.
Example Training Marketing blueLagoon someone 08/29/2018
Labor Day Reminder Company Holiday camelot 09/03/2018
etc
etc
Is the best way to achieve this to use a nested CASE WHEN against the meta_value? Or is there a better way?
I also tried including an if statement (below) but that duplicated each row.
if(meta_key = 'corporate_calendar_subcategory',
CASE
WHEN meta_value = 'Marketing' THEn 'blueLagoon'
WHEN meta_value = 'Company Holiday' THEN 'camelot'
END,
'') as color,
Yes, the nested CASE statement would be the right way to go if you know all the categories and colors beforehand. If the category-colors are in another table, you can do either a subselect or a JOIN instead.
Here's an example with nested case:
max(case when meta_key = 'corporate_calendar_subcategory' then
case meta_value
when 'Marketing' then 'blue'
when 'Sales' then 'yellow
when 'Development' then 'red'
end
end)
I'm querying a MySQL db for a report in SSRS 2008, and I have no problem using the following to join two different queries...
SELECT a.arrivalDate, a.order_item_id, b.roomType
FROM
(select order_item_id, meta_value as arrivalDate from `wp_woocommerce_order_itemmeta` WHERE `meta_key` LIKE 'Arrival Date') as a,
(select order_item_id, meta_value as roomType from `wp_woocommerce_order_itemmeta` WHERE `meta_key` LIKE 'type-of-room') as b
WHERE a.order_item_id = b.order_item_id
...but when I try to add a third, it's taking issue with my WHERE clause, but I coulda swore I used to do it this way:
SELECT a.arrivalDate, a.order_item_id, b.roomType, c.retreatDate
FROM
(select order_item_id, meta_value as arrivalDate from `wp_woocommerce_order_itemmeta` WHERE `meta_key` LIKE 'Arrival Date') as a,
(select order_item_id, meta_value as roomType from `wp_woocommerce_order_itemmeta` WHERE `meta_key` LIKE 'type-of-room') as b,
(select order_item_id, meta_value as retreatDate from `wp_woocommerce_order_itemmeta` WHERE `meta_key` LIKE 'retreat-date') as c,
WHERE a.order_item_id = b.order_item_id AND a.order_item_id = c.order_item_id
Any advice?
Never mind, got it! I thought this is what I tried originally, but I must've had a typo. Hopefully, my error will help others stumbling across this in the future:
SELECT a.arrivalDate, a.order_item_id, b.roomType, c.retreatDate
FROM
(select order_item_id, meta_value as arrivalDate from `wp_woocommerce_order_itemmeta` WHERE `meta_key` LIKE 'Arrival Date') as a,
(select order_item_id, meta_value as roomType from `wp_woocommerce_order_itemmeta` WHERE `meta_key` LIKE 'type-of-room') as b,
(select order_item_id, meta_value as retreatDate from `wp_woocommerce_order_itemmeta` WHERE `meta_key` LIKE 'retreat-date') as c
where a.order_item_id = b.order_item_id AND b.order_item_id = c.order_item_id
I would stick with either of the conventional solutions - the first is (IMO) easier to read. The second is typically faster...
Query 1
SELECT order_item_id
, MAX(CASE WHEN meta_key = 'Arrival Date' THEN meta_value END) arrivalDate
, MAX(CASE WHEN meta_key = 'type-of-room' THEN meta_value END) roomType
, MAX(CASE WHEN meta_key = 'retreat-date' THEN meta_value END) retreatDate
FROM wp_woocommerce_order_itemmeta
GROUP
BY order_item_id
Query 2
SELECT DISTINCT x.order_item_id
, arrival.meta_value arrivalDate
, room.meta_value roomType
, date.meta_value retreatDate
FROM wp_woocommerce_order_itemmeta x
LEFT
JOIN wp_woocommerce_order_itemmeta arrival
ON arrival.order_item_id = x.order_item_id
AND arrival.meta_key = 'Arrival Date'
LEFT
JOIN wp_woocommerce_order_itemmeta room
ON room.order_item_id = x.order_item_id
AND room.meta_key = 'type-of-room'
LEFT
JOIN wp_woocommerce_order_itemmeta date
ON date.order_item_id = x.order_item_id;
OK, I may have missed this in the search, but I am unsure of what I am looking for. I have a couple of tables that I need ti generate mailing labels from. Main table has name and surname. Then a second table has multiple rows for data like phon-123415324, address 1- 1 james st etc...There is also a table that bind the data. Here is an example result and the query.
SELECT
users.name,
users.surname,
details.`field`,
details.value
FROM
users
Inner Join details ON details.user_id = users.id
Inner Join bookings ON bookings.guest_id = users.id
WHERE
bookings.sub_event_id = '78'
NAME, SURNAME, field, value
David Oden title Mr
David Oden sex Male
David Oden mobile 0534600594
David Oden company Fterns Group
David Oden position
David Oden address_1 Cnr wtrewr Rd & wert St
David Oden address_2
David Oden suburb wertt Mile wertw
David Oden state MAS
David Oden postcode 14113
David Oden country USA
WHAT I need I all the data i 1 row to export to excel for mailing labels. Sorry if this is really dumb. I have spent about 4 hours researching with no luck.
I need the type to be a column header and the value to be the data.
Shoud read
Title | Name | Surname | Mobile | Company | Address etc.....
MR | David | Oden | 0534600594 | Fterns Group | etc....
Any help would be appreciated/
This is known as a PIVOT function but unfortunately MySQL does not have a PIVOT, so you will have to replicate it use an aggregate function an a CASE statement. If you know the values that you need to include in the query, then you can hard-code them similar to the following:
select
min(case when d.field = 'title' then d.value end) as Title,
u.name,
u.surname,
min(case when d.field = 'sex' then d.value end) as Sex,
min(case when d.field = 'mobile' then d.value end) as Mobile,
min(case when d.field = 'company' then d.value end) as Company,
min(case when d.field = 'position' then d.value end) as Position,
min(case when d.field = 'address_1' then d.value end) as Address_1,
min(case when d.field = 'address_2' then d.value end) as Address_2,
min(case when d.field = 'suburb' then d.value end) as suburb,
min(case when d.field = 'state' then d.value end) as State,
min(case when d.field = 'postcode' then d.value end) as Postcode,
min(case when d.field = 'country' then d.value end) as country
from users u
left join details d
on u.id = d.id
left join bookings b
on u.id = b.guest_id
where b.sub_event_id = 78
group by u.name, u.surname
See SQL Fiddle with demo
But if you have an unknown number of columns or if the value will change, then you will want to perform this dynamically, then you should read the following article on prepared statements:
Dynamic pivot tables (transform rows to columns)
Your code would look like this:
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'min(case when d.field = ''',
d.field,
''' then d.value end) AS ',
d.field
)
) INTO #sql
from users u
left join details d
on u.id = d.d_id;
SET #sql = CONCAT('SELECT u.name,
u.surname, ', #sql, '
from users u
left join details d
on u.id = d.d_id
left join bookings b
on u.id = b.guest_id
where b.sub_event_id = 78
group by u.name, u.surname');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
See SQL Fiddle with Demo
I have a problem with a query:
I have a list of stores, each of these stores has members and there are various categories of membership (Bronze, silver, gold ...)
The tables are: 'shops', 'members', 'membership_cards'.
shops: id, name
members: id, shops_id, membership_id, first_name, last_name
membership_cards: id, description
I need to extract the count of members, grouped by membership of each stores. Can I do this without using a server side language?
The final result should be something like:
Store's name, n°bronze members, n°silver_members, n°gold_members ....
Based on what you provided, you want a query like:
select shopid,
sum(case when c.cardtype = 'Bronze' then 1 else 0 end) as Bronze,
sum(case when c.cardtype = 'Silver' then 1 else 0 end) as Silver,
sum(case when c.cardtype = 'Gold' then 1 else 0 end) as Gold
from shops s left outer join
members m
on s.shopid = m.shopid left outer join
cards c
on c.memberid = m.memberid
group by shopid
If you want to know the number of members, rather than of cards in each group (if members can have more than one card), then replace the sum() expression with:
count(case when c.cardtype = 'Bronze' then m.memberid end)
Without knowing your database schema, it's a bit hard to answer that question, but something like the following should do the job:
SELECT shop.name,
SUM(CASE WHEN membership_cards.category = 'Bronze' THEN 1 ELSE 0 END) AS Bronze,
SUM(CASE WHEN membership_cards.category = 'Silver'THEN 1 ELSE 0 END) AS Silver,
SUM(CASE WHEN membership_cards.category = 'Gold' THEN 1 ELSE 0 END) AS Gold
FROM shops
INNER JOIN members
ON shop.id = members.shopid
INNER JOIN membership_cards
ON members.id = membership_cards.memberid
GROUP BY shop.name
Just change the column names to the names you are using.
SELECT B.name,A.Bronze,A.Silver,A.Gold
FROM
(
SELECT S.id,
SUM(IF(IFNULL(C.cardtype,'')='Bronze',1,0)) Bronze,
SUM(IF(IFNULL(C.cardtype,'')='Silver',1,0)) Silver,
SUM(IF(IFNULL(C.cardtype,'')='Gold' ,1,0)) Gold
FROM shops S
LEFT JOIN members M ON S.id = M.shops_id
LEFT JOIN membership_cards C ON M.membership_id = C.id
GROUP BY S.id
) A
INNER JOIN shops B USING (id);
I used the IFNULL function in case any member has no cards