I hope you can get me here. I'm working on a PMS system and I want to run a simple SELECT statement to get a list of secret codes for my customers based on which of their parcels have arrived and the transaction type. The 'transferConfirmation' table already has the customer ID and the secret code and displays one row for each instance but for some reason, when i use the following query:
SELECT `tc`.`transferID` AS `transferID`,
`c`.`firstName` AS `firstName`,
`c`.`lastName` AS `lastName`,
`tc`.`secretCode` AS `secretCode`,
'Purchase Order' AS `transactionType`
FROM (((((`db`.`transferconfirmation` `tc`
JOIN `db`.`customer` `c` on((`tc`.`customerID` = `c`.`customerID`)))
JOIN `db`.`transfer` `t` on((`t`.`transferID` = `tc`.`transferID`)))
JOIN `db`.`transferentry` `te` on((`t`.`transferID` = `te`.`transferID`)))
JOIN `db`.`purchaseorder` `po` on((`te`.`referenceID` = `po`.`purchaseOrderID`)))
JOIN `db`.`purchaseorderentry` `poe` on(((`po`.`purchaseOrderID` = `poe`.`purchaseOrderID`)
AND (`te`.`referenceEntryID` = `poe`.`purchaseOrderEntryID`))))
WHERE (`poe`.`collectionStatus` = 0)
UNION ALL
SELECT `tc`.`transferID` AS `transferID`,
`c`.`firstName` AS `firstName`,
`c`.`lastName` AS `lastName`,
`tc`.`secretCode` AS `secretCode`,
'Shipping Order' AS `transactionType`
FROM (((((`db`.`transferconfirmation` `tc`
JOIN `db`.`customer` `c` on((`tc`.`customerID` = `c`.`customerID`)))
JOIN `db`.`transfer` `t` on((`t`.`transferID` = `tc`.`transferID`)))
JOIN `db`.`transferentry` `te` on((`t`.`transferID` = `te`.`transferID`)))
JOIN `db`.`shippingorder` `so` on((`te`.`referenceID` = `so`.`shippingOrderID`)))
JOIN `db`.`shippingorderentry` `soe` on(((`so`.`shippingOrderID` = `soe`.`shippingOrderID`)
AND (`te`.`referenceEntryID` = `soe`.`shippingOrderEntryID`))))
WHERE (`soe`.`collectionstatus` = 0)
I keep getting results with duplicate data only difference is with the transaction. I guess my question is, if the secret code has been selected once, how to I prevent any other row from displaying the same code.
Use the UNION operator. The UNION operator will remove duplicate records from each query (UNION ALL would retain them).
SELECT transferID, firstName, lastName, secretCode,
'Purchase Order' AS transactionType
FROM ...
UNION
SELECT transferID, firstName, lastName, secretCode,
'Purchase Order' AS transactionType
FROM ...
Related
I've a SELECT which checks a status of active alarms (icinga).
This select joins different tables and until here all ok.
On the result I've as value/column an object_id as well. I would like to add a column to that select that could be empty or not, because, searching that 'object_id' on a different table, I could get a value or not. This accessory table is structured having: object_id, varname, varvalue.
So, i.e., my SELECT returns those values:
`name`, `object_id`, `status`
`Hello`, `123456`, `OK`
I would add the column City that should compared to a table having:
`object_id`, `varname`, `varvalue`
`123456`, `city`, `Rome`
`123456`, `lake`, `Garda`
`789789`, `city`, `Milano`
So that if the second table has object_id = 123456 AND city = Rome the result should be:
`name`, `object_id`, `status`, `city`
`Hello`, `123456`, `OK`, `Rome`
Otherwise the result should be:
`Hello`, `123456`, `OK`, `UNKNOWN`
How to do that?
Hope I've explained it well :-)
Thanks!
* EDIT *
It's better I explain with real example. My query actually is the following:
select icinga_objects.object_id, icinga_objects.name1 as host_name, icinga_objects.name2 as ServiceName, "service" as Type, icinga_servicestatus.last_check as LastCheckTime, icinga_servicestatus.last_hard_state_change as LastStateChange, TIMEDIFF(now(), icinga_servicestatus.last_hard_state_change) AS SinceTime,
CASE
WHEN icinga_servicestatus.current_state = 0 THEN '0'
WHEN icinga_servicestatus.current_state = 1 THEN '2'
WHEN icinga_servicestatus.current_state = 2 THEN '3'
ELSE '3'
END AS state
FROM icinga_objects, icinga_servicestatus, icinga_services WHERE icinga_servicestatus.service_object_id IN
(SELECT service_object_id FROM icinga_services WHERE icinga_services.host_object_id IN
(SELECT host_object_id FROM icinga_hostgroup_members WHERE hostgroup_id IN
(SELECT hostgroup_id FROM icinga_hostgroups WHERE alias = 'MY-HOSTGROUP-TO-FILTER')
)
)
AND icinga_servicestatus.service_object_id NOT IN
(SELECT service_object_id FROM icinga_services WHERE icinga_services.service_object_id IN (
SELECT object_id FROM icinga_objects WHERE icinga_objects.is_active = 1 AND icinga_objects.object_id IN
(SELECT object_id FROM icinga_customvariables WHERE varvalue = '8x5')
)
)
AND icinga_servicestatus.last_check > NOW() - INTERVAL 3 HOUR
AND icinga_servicestatus.state_type = 1
AND icinga_servicestatus.scheduled_downtime_depth = 0
AND icinga_objects.object_id = icinga_services.service_object_id
AND icinga_servicestatus.service_object_id = icinga_services.service_object_id
AND icinga_servicestatus.current_state = 2
AND icinga_servicestatus.problem_has_been_acknowledged = 0
This gives me as result, in example:
`object_id`, `host_name`, `ServiceName`, `Type`, `LastCheckTime`, `LastStateChange`, `SinceTime`, `State`
`123456`, `myHostName`, `myServiceName`, `service`, `2020-04-29 17:19:21`, `2020-04-28 14:50:27`, `26:32:51`, `3`
Here I would like to add the column.
So, now if I search object_id into icinga_customvariables I could find entries, or not. In Example, searching object_id = 123456 I have 4 records, but ONLY one having varname = NAME_IM_SEARCHING and so I need to add to the above result the corresponding of varvalue searching icinga_customvariables.object_id = '123456' AND varname = NAME_IM_SEARCHING. IF there are NO results, then the added cloumn should be UNKNOWN, otherwise the added column should be = icinga_customvariables.varvalue.
How to add it? :-)
You can place your query into a "table expression" so it becomes simpler to join it to the other_table. For example:
select
q.*,
coalesce(o.varvalue, 'UNKNOWN') as city
from (
-- your existing query here
) q
left join other_table o on o.object_id = q.object_id and o.varname = 'city'
EDIT: Joining multiple times
As requested if you need to extract more city names using another column, or if you want to extract against another table altogether, you can add an extra LEFT JOIN. For example:
select
q.*,
coalesce(o.varvalue, 'UNKNOWN') as city,
coalesce(o2.varvalue, 'UNKNOWN') as lake
from (
-- your existing query here
) q
left join other_table o on o.object_id = q.object_id and o.varname = 'city'
left join other_table o2 on o.object_id = q.object_id and o2.varname = 'lake'
My query shows an error(an expression was expected near DISTINCT), i dont know how to resolve it, if i remove the first INSERT query line, values are selecting properly, if i add insert it shows error, any help could be useful thanks in advance.
INSERT INTO normal_days (user_id, department_id,designation_id,date_cur,clock_in,clock_out)
SELECT DISTINCT clo.user_id, design.department_id , uses.designation_id, clo.date,clo.clock_in, clo.clock_out
FROM clock clo
INNER JOIN holidays AS hol ON hol.date != clo.date
INNER JOIN users AS uses ON clo.user_id = uses.id
INNER JOIN designations AS design ON design.id = uses.designation_id
WHERE date(clo.created_at) = "2016-06-23"
AND TIMESTAMPDIFF(second,clo.clock_in, clo.clock_out) = 28800
AND !(DAYOFWEEK(clo.date)=7)
AND !(DAYOFWEEK(clo.date)=1);
INSERT INTO normal_days (user_id, department_id,designation_id,date_cur,clock_in,clock_out)
SELECT clo.user_id, design.department_id , uses.designation_id, clo.date, clo.clock_in, clo.clock_out
FROM clock clo
LEFT JOIN holidays AS hol ON hol.date = clo.date
INNER JOIN users AS uses ON clo.user_id = uses.id
INNER JOIN designations AS design ON design.id = uses.designation_id
WHERE date(clo.created_at) = "2016-06-23"
AND TIMESTAMPDIFF(second,clo.clock_in, clo.clock_out) = 28800
AND !(DAYOFWEEK(clo.date)=7)
AND !(DAYOFWEEK(clo.date)=1)
AND hol.date is NULL ;
Hello, I have two tables and one junction table. And I want to find all estates, that has one or multiple comforts. I wrote this query (postrgreSql):
SELECT DISTINCT "estates".*
FROM "estates"
LEFT JOIN "estate_comforts"
ON "estates"."id" = "estate_comforts"."estate_id"
WHERE "estate_comforts"."comfort_id" IN ( '1', '2' )
It finding estates that has the first comfort OR the second, but I need to search in "AND" mode.
This project using Yii2 framewors, so plain sql or ActiveRecord statement are acceptable.
Update. This query select all esates, regardless of the comforts
SELECT DISTINCT "estates".*
FROM "estates"
LEFT JOIN "estate_comforts"
ON "estates"."id" = "estate_comforts"."estate_id"
AND "estate_comforts"."comfort_id" IN ( '1', '2' )
Either JOIN estate_comforts twice, one time for comfort_id 1, and another time for comfort_id 2:
SELECT DISTINCT "estates".*
FROM "estates"
INNER JOIN "estate_comforts" ec1
ON "estates"."id" = ec1."estate_id"
INNER JOIN "estate_comforts" ec2
ON "estates"."id" = ec2."estate_id"
WHERE ec1."comfort_id" = '1'
AND ec2."comfort_id" = '2'
Alternatively, do a GROUP BY on estate_comforts to find estate_id with at least two different comfort_id values. Join with that result:
select e.*
from "estates" e
join (select "estate_id"
from "estate_comforts"
WHERE "comfort_id" IN ( '1', '2' )
group by "estate_id"
having count(distinct "comfort_id") >= 2) ec ON e."id" = ec."estate_id"
I have an online store, two views because my products could come from either my packages table or sessions table. The prices are joined from the price table.
The two views work fine on their own, but when I combine there usage I get no results.
I want my shipping guy to only see the items he should ship, not the digital items, namely, those with delivery format equal to 'DVD'.
session view:
select
`ats_store`.`order`.`payment_type` AS `payment_type`,
`production_www`.`paypal_transactions`.`createdOn` AS `order_date`,
`production_www`.`paypal_transactions`.`FIRSTNAME` AS `firstname`,
`production_www`.`paypal_transactions`.`LASTNAME` AS `lastname`,
`ats_store`.`order`.`id` AS `order_id`,
`ats_store`.`order`.`customerid` AS `customerid`,
`ats_store`.`order`.`shipping_address_id` AS `shipping_address_id`,
`ats_store`.`order`.`status` AS `status`,
`ats_store`.`order_items`.`product_id` AS `product_id`,
`ats_store`.`shipping_address`.`country` AS `country`,
`ats_store`.`shipping_address`.`street_1` AS `street1`,
`ats_store`.`shipping_address`.`street_2` AS `street2`,
`ats_store`.`shipping_address`.`street_3` AS `street3`,
`ats_store`.`shipping_address`.`city` AS `city`,
`ats_store`.`shipping_address`.`state_and_province` AS `state`,
`ats_store`.`shipping_address`.`zip_code` AS `zip`,
group_concat(`production_cache_salesforce_repl`.`ats_conference_session__c`.`Name`,
'(',
`price`.`Delivery_Format__c`,
')'
order by `production_cache_salesforce_repl`.`ats_conference_session__c`.`sort_code__c` ASC
separator ',') AS `session_products`
from
(((((`ats_store`.`order`
left join `ats_store`.`shipping_address` ON ((`ats_store`.`shipping_address`.`id` = `ats_store`.`order`.`shipping_address_id`)))
join `ats_store`.`order_items` ON ((`ats_store`.`order_items`.`order_id` = `ats_store`.`order`.`id`)))
join `production_cache_salesforce_repl`.`ats_store_price__c` `price` ON ((`price`.`Id` = `ats_store`.`order_items`.`product_id`)))
join `production_cache_salesforce_repl`.`ats_conference_session__c` ON ((`production_cache_salesforce_repl`.`ats_conference_session__c`.`Id` = convert( `price`.`ATS_Conference_Session__c` using utf8))))
left join `production_www`.`paypal_transactions` ON ((`production_www`.`paypal_transactions`.`id` = `ats_store`.`order`.`paypal_transaction_id`)))
where
((`ats_store`.`order`.`shipping_address_id` <> -(1))
and (`production_www`.`paypal_transactions`.`COMMENT1` = 'ATS Web Store')
and (`production_www`.`paypal_transactions`.`RESPMSG` = 'Approved')
and (`price`.`Delivery_Format__c` = 'DVD'))
group by `ats_store`.`order`.`id`
order by `production_www`.`paypal_transactions`.`createdOn`
package view:
select
`ats_store`.`order`.`payment_type` AS `payment_type`,
`production_www`.`paypal_transactions`.`createdOn` AS `order_date`,
`production_www`.`paypal_transactions`.`FIRSTNAME` AS `firstname`,
`production_www`.`paypal_transactions`.`LASTNAME` AS `lastname`,
`ats_store`.`order`.`id` AS `order_id`,
`ats_store`.`order`.`customerid` AS `customerid`,
`ats_store`.`order`.`shipping_address_id` AS `shipping_address_id`,
`ats_store`.`order`.`status` AS `status`,
`ats_store`.`order_items`.`product_id` AS `product_id`,
`ats_store`.`shipping_address`.`country` AS `country`,
`ats_store`.`shipping_address`.`street_1` AS `street1`,
`ats_store`.`shipping_address`.`street_2` AS `street2`,
`ats_store`.`shipping_address`.`street_3` AS `street3`,
`ats_store`.`shipping_address`.`city` AS `city`,
`ats_store`.`shipping_address`.`state_and_province` AS `state`,
`ats_store`.`shipping_address`.`zip_code` AS `zip`,
`price`.`Delivery_Format__c` AS `delivery_format`,
group_concat(`production_cache_salesforce_repl`.`ats_store_package__c`.`Package_Code__c`,
'(',
`price`.`Delivery_Format__c`,
')'
order by `production_cache_salesforce_repl`.`ats_store_package__c`.`Package_Code__c` ASC
separator ',') AS `package_products`
from
(((((`ats_store`.`order`
left join `ats_store`.`shipping_address` ON ((`ats_store`.`shipping_address`.`id` = `ats_store`.`order`.`shipping_address_id`)))
join `ats_store`.`order_items` ON ((`ats_store`.`order_items`.`order_id` = `ats_store`.`order`.`id`)))
join `production_cache_salesforce_repl`.`ats_store_price__c` `price` ON ((`price`.`Id` = `ats_store`.`order_items`.`product_id`)))
join `production_cache_salesforce_repl`.`ats_store_package__c` ON ((`production_cache_salesforce_repl`.`ats_store_package__c`.`Id` = convert( `price`.`ATS_Store_Package__c` using utf8))))
left join `production_www`.`paypal_transactions` ON ((`production_www`.`paypal_transactions`.`id` = `ats_store`.`order`.`paypal_transaction_id`)))
where
((`ats_store`.`order`.`shipping_address_id` <> -(1))
and (`production_www`.`paypal_transactions`.`COMMENT1` = 'ATS Web Store')
and (`production_www`.`paypal_transactions`.`RESPMSG` = 'Approved')
and (`price`.`Delivery_Format__c` = 'DVD'))
group by `ats_store`.`order`.`id`
order by `production_www`.`paypal_transactions`.`createdOn`
Here is the query that uses both views:
select *,group_concat(pv.package_products,',',sv.session_products) as products from ats_store.shipping_orders_sessions_view sv,ats_store.shipping_orders_packages_view pv
where sv.order_id = pv.order_id
group by sv.order_id
If I remove from the VIEWS and (price.Delivery_Format__c= 'DVD') I can get the orders, but the digital and DVD products are shown. I only want my shipping guy to see items he should ship, the DVDs.
Assuming your two views are clean and working:
Let's work on that query that joins them.
Here's what you have, rewritten to use an explicit join.
select *, /* query with problems */
group_concat(pv.package_products,',',sv.session_products) as products
from ats_store.shipping_orders_sessions_view sv
join ats_store.shipping_orders_packages_view pv on sv.order_id = pv.order_id
group by sv.order_id
What's wrong here?
First, pro tip: don't use select * in complex queries.
Second, select * guarantees random nonsense in your output resultset because you're using a harmful nonstandard MySQL hackstension. Read this: http://dev.mysql.com/doc/refman/5.5/en/group-by-extensions.html You should mention each non-aggregated column in your result set in your GROUP BY clause.
Third, you probably want
GROUP_CONCAT(CONCAT(pv.package_products,',',sv.session_product)) AS products
to make sure you are using the aggregating function GROUP_CONCAT() properly.
So here is a better query.
select sv.order_id,
GROUP_CONCAT(CONCAT(pv.package_products,',',sv.session_product)) AS products
from ats_store.shipping_orders_sessions_view sv
join ats_store.shipping_orders_packages_view pv on sv.order_id = pv.order_id
group by sv.order_id
EDIT: This will yield a result set with one row per distinct order_id that mentions all the products in each order. If you wish to include only certain items, for example those with delivery_format = 'DVD', you need to add a WHERE clause. It looks like your package view exposes that column. So try this:
select sv.order_id,
GROUP_CONCAT(CONCAT(pv.package_products,',',sv.session_product)) AS products
from ats_store.shipping_orders_sessions_view sv
join ats_store.shipping_orders_packages_view pv on sv.order_id = pv.order_id
where pv.delivery_format = 'DVD'
group by sv.order_id
I don't understand your schema well enough to give you better advice than this. I can see that your views are quite complex.
I have an application where a lot of options can be selected where there are four tables and possible 4 different terms from each filter and also additional for if we take value count and i am no good with queries just know how to get the desired result.So the queries can be like:
select distinct(maindbgroupid) from ((SELECT mainDBGroupID from
groupstatisticsdata.seniority where ( `name` = 'Senior' )AND maindbgroupid in (SELECT
mainDBGroupID from groupstatisticsdata.Function where ( `name` = 'Information Technology'
)AND (`Value` >1000) AND maindbgroupid in (SELECT mainDBGroupID from
groupstatisticsdata.Industry where ( `name` = 'Information Technology and Services' )AND
(`Value` >1000))))) t join maingroupdb.campaigns on campaigns.groupid=t.maindbgroupid
where campaigns.campaignName='Campaign1101'
This is one example , how to improve it please as i always get timeout when i use more than one filter.
What i am doing in the query is an intersect between the tables.
Try this ::
select distinct(mainDBGroupID)
from
groupstatisticsdata.seniority
inner join groupstatisticsdata.Function on (groupstatisticsdata.seniority.maindbgroupid=groupstatisticsdata.Function.mainDBGroupID)
inner join groupstatisticsdata.Industry on (groupstatisticsdata.Industry.mainDBGroupID=groupstatisticsdata.seniority.maindbgroupid)
inner join maingroupdb.campaigns on campaigns.groupid=t.maindbgroupid
where groupstatisticsdata.seniority.`name` = 'Senior' AND
groupstatisticsdata.Function.`name` = 'Information Technology'
AND `Value` >1000
AND maindbgroupid
AND groupstatisticsdata.Industry.`name` = 'Information Technology and Services' )
AND
groupstatisticsdata.Industry.`Value` >1000
AND campaigns.campaignName='Campaign1101'