How to use select with update query ? mysql - mysql

I want to count points for each business for having deals or gallery :
so if the business has un empty deal, or has at least one gallery , business_data_count should be 2.
this what i've tried :
UPDATE `business` businessTable SET
business_data_count
=
sum(
(
SELECT
CASE
WHEN count(*)>= 1 then count(*)
ELSE 0
END as points
FROM gallery WHERE bussId=businessTable.bussId
)
+
(
SELECT
case
WHEN deal!='' then 1
ELSE 0
end
FROM business WHERE bussId=businessTable.bussId
)
where 1
but i got this error :
you cant specify table business for update
How to fix this ?

There's no need to do a separate select from the update table. Try this instead (untested):
UPDATE business
SET business_data_count = (deal != '')
+ (SELECT COUNT(*)
FROM gallery
WHERE bussId = business.bussId);
On a separate note, it's generally bad practice to store data that can be easily extracted with a query, such as the above.

I think you have a typo.
I think you should have:
UPDATE `business`.businessTable SET
instead of
UPDATE `business` businessTable SET
If you use the schema when defining your table in your query, you need to separate them with a dot (.).
Maybe it is not the only problem, but that's the first that comes to mind.

Related

Query to find entries and transpose

I've got a machine log available in an SQL table. I can do a bit in SQL, but I'm not good enough to process the following:
In the data column there are entries containing "RUNPGM: Recipe name" and "RUNBRKPGM: Recipe name"
What I want is a view containing 4 columns:
TimeStamp RUNPGM
TimeStamp RUNBRKPGM
Recipe Name
Time Difference in seconds
There is a bit of a catch:
Sometimes the machine logs an empty RUNBRKPGM that should be ignored
The RUNBRKPGM is sometimes logged with an error message. This entry should also be ignored.
It's always the RUNBRKPGM entry with just the recipe name that's the actual end of the recipe.
NOTE: I understand this is not a full/complete answer, but with info available in question as of now, I believe it at least helps give a starting point since this is too complicated (and formatted) to put in the comments:
If Recipe is everything in the DATA field except the 'RUNPGM = ' part you can do somethign similar to this:
SELECT
-- will give you a col for TimeStamp for records with RUNPGM
CASE WHEN DATA LIKE 'RUNPGM%' THEN TS ELSE '' END AS RUNPGM_TimeStamp,
-- will give you a col for TimeStamp for records with RUNBRKPGM
CASE WHEN DATA LIKE 'RUNBRKPGM%' THEN TS ELSE '' END AS RUNBRKPGM_TimeStamp,
-- will give you everything after the RUNPGM = (which I think is the recipe you are referring to)
CASE WHEN DATA LIKE 'RUNPGM%' THEN REPLACE(DATA, 'RUNPGM = ', '' AS RUNPGM_Recipe,
-- will give you everything after the RUNBRKPGM = (which I think is the recipe you are referring to)
CASE WHEN DATA LIKE 'RUNBRKPGM:%' THEN REPLACE(DATA, 'RUNBRKPGM = ', '' AS RUNPGM_Recipe
FROM TableName
Im not sure what columns you want to get the Time Difference on though so I dont have that column in here.
Then if you need to do additional logic/formatting on the columns once they are separated you can put the above in a sub select.
As a first swing, I'd try the following:
Create a view that uses string splitting to break the DATA column into a its parts (e.g. RunType and RecipeName)
Create a simple select that outputs the recipe name and tstamp where the runtype is RUNPGM.
Then add an OUTER APPLY:
Essentially, joining onto itself.
SELECT
t1.RecipeName,
t1.TimeStamp AS Start,
t2.TimeStamp AS Stop
--date func to get run time, pseudo DATEDIFF(xx,t1.TimeStamp, t2.TimeStamp) as RunTime
FROM newView t1
OUTER APPLY ( SELECT TOP ( 1 ) *
FROM newView x
WHERE x.RecipeName = t1.RecipeName
AND RunType = 'RUNBRKPGM'
ORDER BY ID DESC ) t2
WHERE t1.RunType = 'RUNPGM';

Multiplet select statements, each one uses CASE and return two values

i have the follwoing query:
SELECT COALESCE(income_adsense, income_adsense_u) AS "REV",
CASE COALESCE(income_adsense, income_adsense_u)
WHEN income_adsense THEN "REAL"
WHEN income_adsense_u THEN "USER"
END AS source
FROM revenue_report LIMIT 1;
which will return answer like this:
REV | source
376 | REAL
now the query works fine but the problem is i want to execute this select couple of times for different entity (adsense in the example).
the best i could get is this:
SELECT rr.site_id, ws.website_name,
CASE COALESCE(income_adsense, income_adsense_u)
WHEN income_adsense THEN "REAL"
WHEN income_adsense_u THEN "USER"
END AS adsense_source,
CASE COALESCE(income_taboola, income_taboola_u)
WHEN income_taboola THEN "REAL"
WHEN income_taboola_u THEN "USER"
END AS taboola_source
FROM revenue_report rr
INNER JOIN websites ws ON ws.website_id = rr.site_id
WHERE (data_date BETWEEN '2017-03-18' AND '2017-03-18')
GROUP BY site_id
LIMIT 1
but the problem here is i'm missing the "REV" value from the upper example. I know it doesn't exists in the second query, but this is the last working attempt. any idea how can i add the "REV" value logic to the second query?
in the second query i will get this structure of result:
site_id|website_name|adsense_source|taboola_source
but here im missing the COALESCE result from the first query which in the example was 376
Well why can't you just include it in your SELECT list like
SELECT rr.site_id, ws.website_name,
COALESCE(income_adsense, income_adsense_u) AS "REV", //Here
CASE COALESCE(income_adsense, income_adsense_u)
WHEN income_adsense THEN "REAL"
WHEN income_adsense_u THEN "USER"
END AS adsense_source,
CASE COALESCE(income_gol, income_gol_u)
WHEN income_taboola THEN "REAL"
WHEN income_taboola_u THEN "USER"
END AS taboola_source
FROM revenue_report rr
INNER JOIN websites ws ON ws.website_id = rr.site_id
WHERE (data_date BETWEEN '2017-03-18' AND '2017-03-18')
GROUP BY site_id
LIMIT 1

How to hide the Repeated record in SQL

Using this query:
SELECT
linerbltbl.billofladingid,
linerbltbl.grossweighttotal,
linerb‌​ltbl.netweighttotal,
linerblwisecontainerdetailstbl.containertype,
linerblwisecont‌​ainerdetailstbl.cont‌​ainernumber,
linerblwisecontainerdetailstbl.sealnumber,
linerblwisecontain‌​erdetailstbl.princip‌​lecharge
FROM linerbltbl,
linerblwisecontainerdetailstbl
WHERE linerbltbl.shippername IS NOT NULL
AND linerbltbl.billofladingid =
linerblwisecontainerdetailstbl.bil‌​lofladingid
See this image. It shows what my output IS and what I would like it to be.
You will note that the repeated data is blanked out. Is there a way to do this in my query?
First of all, I think you are going about this wrong. While you CAN do this from within the query itself (see this page) you are probably better off doing it in whatever is consuming the output. For example, if you are taking this data and pasting it into MS Excel, you could check out this post which does is via conditional formatting. If you are consuming it from inside code, you can add logic to handle it there (since I don't know what you are going to do with it, it's hard to add any examples).
But, if you insist on doing it from within SQL it's going to be something to this effect (borrowing from the linked example):
;with t as
(SELECT
linerbltbl.billofladingid,
linerbltbl.grossweighttotal,
linerb‌​ltbl.netweighttotal,
linerblwisecontainerdetailstbl.containertype,
linerblwisecont‌​ainerdetailstbl.cont‌​ainernumber,
linerblwisecontainerdetailstbl.sealnumber,
linerblwisecontain‌​erdetailstbl.princip‌​lecharge
FROM linerbltbl,
linerblwisecontainerdetailstbl
WHERE linerbltbl.shippername IS NOT NULL
AND linerbltbl.billofladingid =
linerblwisecontainerdetailstbl.bil‌​lofladingid
)
SELECT
CASE WHEN RR = 1 THEN billofladingid ELSE '' END BillOfLadingID,
CASE WHEN RR = 1 THEN grossweighttotal ELSE '' END GrossWeight,
CASE WHEN RR = 1 THEN netweighttotal ELSE '' END NetWeight,
containertype,
cont‌​ainernumber,
sealnumber,
princip‌​lecharge
FROM
(SELECT (ROW_NUMBER() OVER(PARTITION BY billofladingid ORDER BY billofladingid, grossweighttotal)) [RR], *
FROM t) SUBQUERY1

Need help in writing Efficient SQL query

I have the following query, written inside perl script:
insert into #temp_table
select distinct bv.port,bv.sip,avg(bv.bv) bv, isnull(avg(bv.book_sum),0) book_sum,
avg(bv.book_tot) book_tot,
check_null = case when bv.book_sum = null then 0 else 1 end
from table_bv bv, table_group pge, table_master sm
where pge.a_p_g = '$val'
and pge.p_c = bv.port
and bv.r = '$r'
and bv.effective_date = '$date'
and sm.sip = bv.sip
query continued -- need help below (can some one help me make this efficient, or rewriting, I am thinking its wrong)
and ((sm.s_g = 'FE')OR(sm.s_g='CH')OR(sm.s_g='FX')
OR(sm.s_g='SH')OR(sm.s_g='FD')OR(sm.s_g='EY')
OR ((sm.s_t = 'TA' OR sm.s_t='ON')))
query continued below
group by bv.port,bv.sip
query ends
explanation: some $val that contain sip with
s_g ('FE','CH','FX','SH','FD','EY') and
s_t ('TA','ON') have book_sum as null. The temp_table does not take null values,
hence I am inserting them as zero ( isnull(avg(bv.book_sum),0) ) where ever it encounters a null for the following s_g and s_m ONLY.
I have tried making the query as follows but it made my script to stop wroking:
and sm.s_g in ('FE', 'CH','FX','SH','FD','EY')
or sm.s_t in ('TA','ON')`
I know this should be a comment, but I don't have the rep. To me, it looks like it's hanging because you lost your grouping at the end. I think it should be:
and (
sm.s_g in ('FE', 'CH','FX','SH','FD','EY')
or
sm.s_t in ('TA','ON')
)
Note the parentheses. Otherwise, you're asking for all of the earlier conditions, OR that sm.s_t is one of TA or ON, which is a much larger set than you're anticipating, which may cause it to spin.

MySQL row subquery (multiple columns) with CASE (not in where-clause)

I want to retrieve two columns from the same table, but only if a certain column in the current row isn't set. With just one column to retrieve, there is no problem. Once I need another column, it appears that I need another subquery with another case-clause, but that seems really ineffective. I've never used Joins before, but I'm thinking it's probably really complicated with the case clause?!
I thought the beauty of it was that it actually only executed the (as I heard) wasteful subquery in the few cases when it's needed.
In the docs, I found that comparisons using ROW() are apparently possible. Is there an equivalent for retrieving the columns with AS?
Thank you for any hints, if it only works with Joins, please give me a push in the right direction since they seem kind of complicated and with the case clause it's probably gonna be a mess if I just go ahead.
Ruben
SELECT id, bekannt, (
CASE WHEN bekannt = ''
THEN (
SELECT bekannt
FROM vokabeln AS v2
WHERE v2.id = vokabeln.hinweis
LIMIT 1
)
ELSE NULL
END
) AS lueckentext, (
CASE WHEN bekannt = ''
THEN (
SELECT hinweis
FROM vokabeln AS v2
WHERE v2.id = vokabeln.hinweis
LIMIT 1
)
ELSE NULL
END
) AS lthinweis
FROM vokabeln
WHERE nutzer = 'test'
I'd code it as:
SELECT
v1.id, v1.bekannt, v2.bekannt AS lueckentext, v2.hinweis AS lthinweis
FROM
vokabeln AS v1
LEFT OUTER JOIN vokabeln AS v2
ON (v1.bekannt='' AND v2.id = v1.hinweis)
WHERE
v1.nutzer='test'