This code runs fine. Pay special attention to the 'AS commercial' subquery field. It works.
SELECT `Contacts`.`id`,
(
SELECT `team_members`.`id`
FROM team_members
INNER JOIN team_categories_team_members AS memcat
ON `team_members`.`id` = `memcat`.`team_member_id`
WHERE `memcat`.`team_category_id` =3
) AS commercial
FROM `oys001`.`team_members` AS `Contacts`
JOIN `oys001`.`brands_team_members` AS `BrandsTeamMember` ON (
`BrandsTeamMember`.`brand_id` =2
AND `BrandsTeamMember`.`team_member_id` = `Contacts`.`id` )
However, now I want to perform a condition on it, so I just add this:
WHERE commercial > 0
And it tells me the field does not exist... What's going wrong here?
Wrap your inital query in brackets
SELECT *
FROM (yourqueryhere) AS `v`
WHERE commercial > 0
Related
i want to update some columns in another table from a query result. I keep getting error. Please help.
Update customer_info
set customer_info.reader_ID = aisle_info.reader_ID,
customer_info.tag_no = tag_logs.tag_no,
customer_info.area = aisle_info.area,
customer_info.max_timestamp = TIMESTAMPDIFF(SECOND,MIN(tag_logs.timestamp),MAX(tag_logs.timestamp))
FROM tag_logs
INNER join aisle_info ON tag_logs.reader_ID = aisle_info.reader_ID
WHERE T.tag_no = 515988190124;
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM tag_logs
INNER join aisle_info ON tag_logs.reader_ID = aisle_info.reader_I' at line 5
You were close. Different databases have slightly different syntax on updates from select/join. Think of MySQL as a select statement, and use the alias of the primary table you are trying to update and then the SET clauses are after that.
So I first will start by writing the SELECT query by itself.
select
CI.Tag_No,
AI.Reader_ID,
AI.Area,
MIN( TL.TimeStamp ) MinTime,
MAX( TL.TimeStamp ) MaxTime
from
customer_info CI
join tag_logs TL
CI.tag_no = TL.tag_no
join aisle_info AI
on TL.Reader_ID = Reader_ID
WHERE
CI.tag_no = 515988190124
group by
CI.Tag_No,
AI.Reader_ID,
AI.Area
So this gives us the final results of what you want, and you can confirm it as needed.
Then apply your update such as
update Customer_Info CIUpd
JOIN
( select
CI.Tag_No,
AI.Reader_ID,
AI.Area,
MIN( TL.TimeStamp ) MinTime,
MAX( TL.TimeStamp ) MaxTime
from
customer_info CI
join tag_logs TL
CI.tag_no = TL.tag_no
join aisle_info AI
on TL.Reader_ID = Reader_ID
WHERE
-- notice your filter is HERE for the one tag_no you want to update
-- and will result with only this on TAG_NO set of values returned
CI.tag_no = 515988190124
group by
CI.Tag_No,
AI.Reader_ID,
AI.Area ) FirstQuery
-- the JOIN will ensure updating only on that one tag_no
ON CIUpd.Tag_No = FirstQuery.Tag_No
set
CIUpd.Reader_ID = FirstQuery.Reader_ID,
CIUpd.Area = FirstQuery.Area,
CIUpd.Max_TimeStamp = TimeStampDiff( second, FirstQuery.MinTime, FirstQuery.MaxTime )
Now this is not a perfect answer as your original query was not a proper query using the MIN() / MAX() context. When doing an aggregate query, you need to apply a group by on all NON aggregate columns. In this case you did not clarify any such group consideration on the Reader_ID and Area which COULD result in multiple rows from your tag_logs and aisle_info tables.
If the aisle info will be the same all the time for a given Tag_No, then that's simple, just skip the grouping on that and change those column retrieve values as MAX() each. if they never change, MAX() or even MIN() will always return the same value and not have an issue with the aggregate query without non-aggregate columns.
If you can provide additional clarification of data, purpose, etc, please edit your original post vs just leaving a comment. Then leave a comment for me to please review with updated info.
I'm having trouble optimising a simple SQL query but having serious issue with timing. I've written it three times and none of them work. Here is the original one I was hoping to work:
SELECT RSKADDR.*
FROM EDW_BASE.RCI_RISK_ADDRESS RSKADDR
INNER JOIN (
SELECT DISTINCT COVER_RISK_ID
FROM EDW_BASE.RCI_COVER_RISK_MASTER RSKMASTER
INNER JOIN
(SELECT DISTINCT CONTACT_ID, FOLLOW_UP_DATE
FROM EDW_STG.STG_CIM_SVOM03
WHERE OUTSTANDING = 1 AND QUEUE = 'CIM Update for Contact Address') ADDR_WF
ON RSKMASTER.CONTACT_CODE = ADDR_WF.CONTACT_ID
WHERE RSKMASTER.IS_STORNO != 1
AND RSKMASTER.PRODUCT_CODE = 'HOME'
AND ADDR_WF.FOLLOW_UP_DATE >= RSKMASTER.COVER_EFF_START_DATE
AND RSKMASTER.POLICY_STATUS_CODE = 'POLICY'
AND ADDR_WF.FOLLOW_UP_DATE <= RSKMASTER.COVER_EFF_END_DATE
) ACTVRSK
ON ACTVRSK.COVER_RISK_ID = RSKADDR.RISK_ID
The code in the first inner join works fast all the way to the end. That is, the second SELECT query (within the INNER JOIN query of the first and main SELECT query) works fast without a problem. The problem arises when I integrate the second SELECT query inside the INNER JOIN of the main SELECT query (select RSKADDR.*).
Then it seems the execution is never ending!
I tried other ways and same result:
SELECT RSKADDR.*
FROM EDW_BASE.RCI_RISK_ADDRESS RSKADDR
INNER JOIN EDW_BASE.RCI_COVER_RISK_MASTER RSKMASTER
ON RSKMASTER.COVER_RISK_ID = RSKADDR.RISK_ID
AND RSKMASTER.IS_STORNO != 1
AND RSKMASTER.PRODUCT_CODE = 'HOME'
AND RSKMASTER.POLICY_STATUS_CODE = 'POLICY'
INNER JOIN EDW_STG.STG_CIM_SVOM03 ADDR_WF
ON OUTSTANDING = 1 AND QUEUE = 'CIM Update for Contact Address'
AND RSKMASTER.CONTACT_CODE = ADDR_WF.CONTACT_ID
AND ADDR_WF.FOLLOW_UP_DATE >= RSKMASTER.COVER_EFF_START_DATE
AND ADDR_WF.FOLLOW_UP_DATE <= RSKMASTER.COVER_EFF_END_DATE
It's such an easy query and can't get it to work. How can I do this?
DISTINCT is a costly operation and seldom needed. It often indicates a bad database design or a poorly written query. In your query you are even doing this repeatedly; that doesn't look good.
The second query looks much better. As you say you get the same result, DISTINCT in the first query was superfluous obviously.
I see you doing joins, but all you select is data from one table. So why join then? Select from the table you want data from and put your criteria in WHERE where it belongs.
The following query may be faster, because it plainly shows that we are simply checking whether we find matches in the other tables or not. But then, MySQL was known for not performing too well with IN clauses, so that may depend on the Version you are using.
select *
from edw_base.rci_risk_address
where risk_id in
(
select rm.cover_risk_id
from edw_base.rci_cover_risk_master rm
where rm.is_storno <> 1
and rm.product_code = 'HOME'
and rm.policy_status_code = 'POLICY'
and exists
(
select *
from edw_stg.stg_cim_svom03 adr
where adr.contact_id = rm.contact_code
and adr.follow_up_date >= rm.cover_eff_start_date
and adr.follow_up_date <= rm.cover_eff_end_date
and adr.outstanding = 1
and adr.queue = 'CIM Update for Contact Address'
)
);
Anyway, with your second query or with mine, I suppose the following indexes would help:
create index idx1 on rci_cover_risk_master
(
product_code,
policy_status_code,
is_storno,
contact_code,
cover_eff_start_date,
cover_eff_end_date,
cover_risk_id
);
create index idx2 on stg_cim_svom03
(
contact_id,
follow_up_date,
outstanding,
queue
);
create index idx3 on rci_risk_address(risk_id);
From the query, you only need RSKADDR data, so no need for an INNER JOIN. You can do the same with EXISTS keyword. Try the below query
SELECT RSKADDR.*
FROM EDW_BASE.RCI_RISK_ADDRESS RSKADDR
WHERE EXISTS (
SELECT 1
FROM EDW_BASE.RCI_COVER_RISK_MASTER RSKMASTER
WHERE EXISTS
(SELECT 1
FROM EDW_STG.STG_CIM_SVOM03
WHERE OUTSTANDING = 1 AND QUEUE = 'CIM Update for Contact Address') ADDR_WF
AND RSKMASTER.CONTACT_CODE = ADDR_WF.CONTACT_ID
AND RSKMASTER.IS_STORNO != 1
AND RSKMASTER.PRODUCT_CODE = 'HOME'
AND ADDR_WF.FOLLOW_UP_DATE >= RSKMASTER.COVER_EFF_START_DATE
AND RSKMASTER.POLICY_STATUS_CODE = 'POLICY'
AND ADDR_WF.FOLLOW_UP_DATE <= RSKMASTER.COVER_EFF_END_DATE
)
AND RSKMASTER.COVER_RISK_ID = RSKADDR.RISK_ID
)
Note : I have not tested query as no schema available.
I'm a mysql beginner these days, i appreciate for your advise.
I got a problem my sql query
INSERT IGNORE INTO TB_AUTO_BAN(MEMO, REG_DATE, USER_ID, NAME, PHONE_NUM)
(
SELECT 'test' AS MEMO, NOW() AS REG_DATE, a.USER_ID, a.NAME, a.CONTACT_NUM
FROM TB_CONTACT AS a,TB_CONTACT_GROUP AS b
WHERE b.USER_ID = 'spark#naver.com'
AND b.GROUP_CONTACT_SEQ = IN(12800,12801)
AND a.GROUP_CONTACT_SEQ = b.GROUP_CONTACT_SEQ
Bold text part is the problem, how should I modify it??
Your query looks ok, except for the = in. Only in is needed.
I would write the query as:
INSERT IGNORE INTO TB_AUTO_BAN(MEMO, REG_DATE, USER_ID, NAME, PHONE_NUM)
SELECT 'test' AS MEMO, NOW() AS REG_DATE, c.USER_ID, c.NAME, c.CONTACT_NUM
FROM TB_CONTACT AS c JOIN
TB_CONTACT_GROUP AS cg
ON c.GROUP_CONTACT_SEQ = cg.GROUP_CONTACT_SEQ
WHERE cg.USER_ID= 'spark#naver.com' AND
cg.GROUP_CONTACT_SEQ IN (12800, 12801) ;
In addition to fixing the condition, this changes the table aliases to be abbreviations rather than arbitrary letters. It also uses standard join syntax instead of implicit joins with the condition buried in the where clause.
the equality sign "=" is superfluous. just delete it, and leave: b.GROUP_CONTACT_SEQ IN (12800,12801)
I have a MySQL view defined like this:
SELECT
group_concat(`h`.`name` SEPARATOR ',') AS `hosts`,
`m`.`id` AS `slo_application_id`,
`s`.`application` AS `application`,
`s`.`slo_conformance` AS `slo_conformance`,
`s`.`hourly_conformance` AS `hourly_conformance`,
`s`.`date` AS `date`,
`m`.`slo_profile` AS `slo_profile`
FROM
(
(
`inv_host_slo` `s`
JOIN `slo_host_map` `m` ON (
(
`s`.`application` = `m`.`application_string`
)
)
)
LEFT JOIN `inv_host` `h` ON ((`m`.`host_id` = `h`.`id`))
)
GROUP BY
`s`.`application`
It's very simple, but I'm noticing some strange behavior when I query the view with a WHERE on the date field. If I insert WHERE s.date = '2013-10-22' before the GROUP BY statement in an actual SQL query I get 2425 records, but if I do it to the view directly:
SELECT
*
FROM
v_host_slo_conformance
WHERE
date = '2013-10-22'
I only get 307 records.
This isn't happening on my development database and the only difference is that dev is running 5.5.15, whereas production is running 5.5.14. Is this a bug based on version differences or something I'm overlooking?
Think about the steps.
REAL QUERY
U join
Filter result set by where (date)
You group
this gives you one result set.
IN VIEW
U join
U group by
THIS IS THE VIEW/RESULT SET U WORK ON
U filter the result set.
Two completely different result sets that you work on, obviously will give two different results.
Im trying to build a complex (well...) query with Zend_Db_Table where I will both need to join the original table with an extra table and get some extra info from the original table with zend_db_expr.
However, things go wrong from the start. What I to is this:
$select = $this->getDbTable()->select(Zend_Db_Table::SELECT_WITH_FROM_PART)
->setIntegrityCheck(false);
$select->from( $this->getDbTable() , array(
'*' ,
new Zend_Db_Expr('`end` IS NULL as isnull') ,
new Zend_Db_Expr('`sold` IN (1,2,3) as issold') ,
) );
Zend_Debug::dump( $select->__toString() );exit;
What results in this:
SELECT `items`.*, `items_2`.*, `end` IS NULL as isnull, `sold` IN (1,2,3) as issold FROM `items`
INNER JOIN `items` AS `items_2`
What I need it to be though, at this point before I do the join with the other table, is
SELECT `items`.*, `end` IS NULL as isnull, `sold` IN (1,2,3) as issold FROM `items`
I don't need an inner join with itself, I just need to add those two Zend_Db_Expr to the things that should be selected, after which I'd continue building the query with the join and where's etc. like
$select->joinLeft( ... )
->where(...)
Any ideas? Cheers.
You should not redo a ->from() call, which means yu add a new table in the query.
Instead you should just use ->where()->columns() calls containing you Zend_Db_expr.
edit: sorry for the mistake.