i want include two value in one field am trying this and not able to concat those two filed - salesforce-marketing-cloud

SELECT
m.Subscriber_Key,
m.Email,
CASE
WHEN m.Campaign_ID IS NOT NULL THEN Concat(m.Campaign_ID,',','R.Campaign_ID')
ELSE R.Campaign_ID
END as Campaign_ID
FROM
PROD_Aveenobaby_TW_Profile_Master_test m JOIN PROD_aveenobaby_TW_Registration_Profile_ENH_66170_test R ON m.Email = R.Email

Related

Need help in writing query

I am using below query to fetch the report for 10 different ids using union-all.Is there any way to reduce the query ?
SELECT
sc.consentid,
CASE
WHEN ue.userid IS NULL THEN 'No'
ELSE 'Yes'
END ,
sc.firstname,
sc.lastname,
CASE
WHEN SUM(time_on_page) > 0 THEN ROUND(SUM(time_on_page) / 60, 2)
ELSE 'No videos watched'
END AS timeonpage,
'ID1' ,
CASE
WHEN COUNT(DISTINCT COALESCE(article, video)) > 0 THEN COUNT(DISTINCT COALESCE(article, video))
ELSE 'no video in list watched'
END AS countvideoswatched
FROM
studentconsent AS sc
LEFT JOIN
useremails AS ue USING (email)
LEFT JOIN
masterstats_innodb AS m ON ue.userid = m.user_id
WHERE
(sc.email LIKE '%.it'
AND (sc.consentid IS NOT NULL
AND m.id IS NULL)
OR (m.id IS NOT NULL
AND m.timestamp >= '2020-12-01'
AND (video IN (SELECT
objectid
FROM
playlists
JOIN
playlisttoobjects USING (playlistid)
WHERE
unique_id = 'ID1'
AND objecttype = 'article'))))
GROUP BY sc.consentid
union all (query2 with differentid)....so on
Here I need to use union-all command to combine all 10 select queries with different id.Any way to reduce it?

IF / CASE statement in SQL

I'm really struggling to find an answer to this issue. I want to write an if or case statement that changes a value in another column. If column 'check' is 0 then column 'points' should be 0 as well.
SELECT club_name, COALESCE(club_winner,0) AS 'check', COUNT(*) AS points,
CASE
WHEN check = '0'
THEN points = '0'
ELSE check
END as Saleable
FROM clubs c
LEFT JOIN club_results cr ON c.club_id = cr.club_winner
GROUP BY club_name ORDER BY points DESC
You can't "SET" columns in a case statement, you can return the value. Think of the case statement as a variable column. Return '0' AS Saleable (Or whatever column you wish to name).
SELECT club_name, COALESCE(club_winner,0) AS 'check', COUNT(*) AS points,
CASE
WHEN COALESCE(club_winner,0) = 0
THEN 0
ELSE COUNT(*)
END AS points_or_0_if_check_is_0
FROM clubs c
LEFT JOIN club_results cr ON c.club_id = cr.club_winner
GROUP BY club_name ORDER BY points_or_0_if_check_is_0 DESC
You can select to count only lines matching your left join like so:
SELECT
club_name,
COUNT(
CASE WHEN
club_winner IS NOT NULL
THEN
CR.id
ELSE
NULL
END
) AS `points`
FROM
clubs C
LEFT JOIN
club_results CR ON C.club_id = CR.club_winner
GROUP BY
C.club_id
ORDER BY
points DESC

How to count the results of a where clause in order to calculate a proportion a MYSQL select clause?

I'm starting out with this query, which gives me back 8 records with a "claimed" status. I'm looking to see if any of the addresses in the invites-from-address column are different from that in the moves-from-address column :
SELECT i.id, i.company_id, i.status,
ia_f.base_street as "invites-from-address", a_f.base_street as "moves-from-address",
ia_t.base_street as "invites-to-address", a_t.base_street as "moves-to-address", i.`mover_first_name`,
i.mover_last_name, i.`to_address_id`
FROM invites i
JOIN moves m ON i.id = m.`claimed_invite_id`
JOIN `invite_addresses` ia_f ON ia_f.id = i.`from_address_id`
JOIN addresses a_f ON a_f.id = m.from_address_id
JOIN `invite_addresses` ia_t ON ia_t.id = i.to_address_id
JOIN addresses a_t ON a_t.id = m.to_address_id
WHERE i.`company_id` = 1040345
GROUP BY id
What I'm trying to do in this query below is to create an average_discrepancy column on the fly that shows the proportion of addresses that differ between invites-from-address and moves-from-address. I was able to successfully check for address discrepancies by using a WHERE clause that checks that ia_f.base_street is not equal to a_f.base_street (which are aliased to the columns invites-from-address and moves-from-address respectively) but when I put this WHERE clause inside the count function in my SELECT cause it doesn't work. Is it because I can't place a WHERE clause inside a SELECT or a count function or both? And is there also a problem with trying to divide the results of two calls to the count function in my SELECT clause ?
SELECT i.id, i.company_id, i.status,
count(WHERE ia_f.base_street != a_f.base_street)/count(i.status="claimed") as "average_discrepancy",
ia_f.base_street as "invites-from-address", a_f.base_street as "moves-from-address",
ia_t.base_street as "invites-to-address", a_t.base_street as "moves-to-address",
i.`mover_first_name`,
i.mover_last_name, i.`to_address_id`
FROM invites i
JOIN moves m ON i.id = m.`claimed_invite_id`
JOIN `invite_addresses` ia_f ON ia_f.id = i.`from_address_id`
JOIN addresses a_f ON a_f.id = m.from_address_id
JOIN `invite_addresses` ia_t ON ia_t.id = i.to_address_id
JOIN addresses a_t ON a_t.id = m.to_address_id
WHERE i.`company_id` = 1040345
AND i.status = "claimed"
You need to put this into a SUM instead of a COUNT. Something like this would do the trick:
SELECT i.id, i.company_id, i.status,
SUM(CASE WHEN ia_f.base_street != a_f.base_street THEN 1 ELSE 0 END)/ SUM(CASE WHEN i.status='claimed' THEN 1 ELSE 0 END) as 'average_discrepancy',
ia_f.base_street as 'invites-from-address',
a_f.base_street as 'moves-from-address',
ia_t.base_street as 'invites-to-address',
a_t.base_street as 'moves-to-address',
i.mover_first_name,
i.mover_last_name,
i.to_address_id
FROM invites i
JOIN moves m ON i.id = m.claimed_invite_id
JOIN invite_addresses ia_f ON ia_f.id = i.from_address_id
JOIN addresses a_f ON a_f.id = m.from_address_id
JOIN invite_addresses ia_t ON ia_t.id = i.to_address_id
JOIN addresses a_t ON a_t.id = m.to_address_id
WHERE i.company_id = 1040345
AND i.status = 'claimed'

Order by clause not behaving correctly after several joins

Here is my query:
SELECT DISTINCT `post_data`. * , pv.`seller_id` , pv.`islimited` , pv.`isquantity` , pv.`isslider`, `price`.`original_price` , `price`.`discount_percentage` , `timelimit`.`start_date` , `timelimit`.`expire_date` , `quantity`.`in_stock`, `currency`.`currency_symbol`, `seller`.`directory`, `post_to_cat`.`cat_id`, count(`sales`.`sales_id`) as sale FROM `post_view` AS pv
INNER JOIN `post_data` ON pv.`post_id` = `post_data`.`post_id` AND pv.`status` = 1
INNER JOIN `price` ON pv.`post_id` = `price`.`post_id`
INNER JOIN `currency` ON `price`.`currency_id` = `currency`.`currency_id`
INNER JOIN `seller` ON pv.`seller_id` = `seller`.`seller_id`
INNER JOIN `post_to_cat` ON `post_to_cat`.`cat_id` = 1 AND `post_to_cat`.`post_id` = `post_data`.`post_id`
LEFT JOIN `timelimit` ON ( CASE WHEN pv.`islimited` = 1 THEN `timelimit`.`post_id` ELSE -1 END ) = pv.`post_id`
LEFT JOIN `quantity` ON ( CASE WHEN pv.`isquantity` = 1 THEN `quantity`.`post_id` ELSE -1 END ) = pv.`post_id`
LEFT JOIN `sales` ON `sales`.`post_id` = pv.`post_id` AND `sales`.`status` = 1
WHERE pv.`status` = 1
ORDER BY pv.`post_id` DESC LIMIT 1
The ORDER BY DESC is not working, it just returns the first row from the table, but I want to get the highest post_id value row. What is the mistake I am making?
AS #Alex said in the comments you've got a LIMIT 1 at the end, you should probably bracket the last LEFT JOIN also for readability.
As #McAdam331 said we need data sample and sql fiddle to investigate what is wrong with you query. But at the moment I have some suggestions how to improve and debug your query.
First off all, what do I see the main and very left table in your query is post_view so all other tables should be LEFT JOIN if you want to get the max id. You should use INNER JOIN only if you think that other table could filter your main table somehow and order or result could be other table dependend. But in your case I see no reason to use INNER JOIN.
Second point is your very weird ON conditions:
LEFT JOIN `timelimit` ON ( CASE WHEN pv.`islimited` = 1 THEN `timelimit`.`post_id` ELSE -1 END ) = pv.`post_id`
LEFT JOIN `quantity` ON ( CASE WHEN pv.`isquantity` = 1 THEN `quantity`.`post_id` ELSE -1 END ) = pv.`post_id`
I have converted them into another one
CASE WHEN pv.`islimited`=1 THEN `timelimit`.`start_date` ELSE NULL END as start_date ,
CASE WHEN pv.`islimited`=1 THEN `timelimit`.`expire_date` ELSE NULL END as expire_date,
CASE WHEN pv.`isquantity`=1 THEN `quantity`.`in_stock` ELSE NULL END as in_stock,
But I still don't like it. It seems very useless to me. And has no sense when I read CASE WHEN pv.islimited=1 THEN timelimit.start_date ELSE NULL END as start_date so if flag pv.islimited=0 you don't need start_date? Are you sure?
And the last thing I can suggest: try to use my or even your query. But add every table by step while debugging. So First query just:
SELECT
pv.`post_id`, pv.`seller_id` , pv.`islimited` , pv.`isquantity` ,
pv.`isslider`
FROM `post_view` AS pv
WHERE pv.`status` = 1
ORDER BY pv.`post_id` DESC
LIMIT 1
If it returns correct post_id add next table:
SELECT
pv.`post_id`, pv.`seller_id` , pv.`islimited` , pv.`isquantity` ,
pv.`isslider`,
`post_data`. *
FROM `post_view` AS pv
LEFT JOIN `post_data`
ON pv.`post_id` = `post_data`.`post_id`
WHERE pv.`status` = 1
AND `post_data`.`slug` = 'abc'
ORDER BY pv.`post_id` DESC
LIMIT 1
Check the result. And continue step by step.
Yes it takes time. But that is debugging process. It could be the fastest way to get that query done. :-)
SELECT `post_data`. * ,
pv.`post_id`, pv.`seller_id` , pv.`islimited` , pv.`isquantity` ,
pv.`isslider`, `price`.`original_price` , `price`.`discount_percentage` ,
CASE WHEN pv.`islimited`=1 THEN `timelimit`.`start_date` ELSE NULL END as start_date ,
CASE WHEN pv.`islimited`=1 THEN `timelimit`.`expire_date` ELSE NULL END as expire_date,
CASE WHEN pv.`isquantity`=1 THEN `quantity`.`in_stock` ELSE NULL END as in_stock,
`currency`.`currency_symbol`, `seller`.`directory`, `post_to_cat`.`cat_id`, count(`sales`.`sales_id`) as sale
FROM `post_view` AS pv
LEFT JOIN `post_data`
ON pv.`post_id` = `post_data`.`post_id`
LEFT JOIN `price`
ON pv.`post_id` = `price`.`post_id`
LEFT JOIN `currency`
ON `price`.`currency_id` = `currency`.`currency_id`
LEFT JOIN `seller`
ON pv.`seller_id` = `seller`.`seller_id`
LEFT JOIN `post_to_cat`
ON `post_to_cat`.`cat_id` = 1
AND `post_to_cat`.`post_id` = pv.`post_id`
LEFT JOIN `timelimit`
ON `timelimit`.`post_id` = pv.`post_id`
LEFT JOIN `quantity`
ON quantity`.`post_id` = pv.`post_id`
LEFT JOIN `sales`
ON `sales`.`post_id` = pv.`post_id`
AND `sales`.`status` = 1
WHERE pv.`status` = 1
AND `post_data`.`slug` = 'abc'
GROUP BY pv.`post_id`
ORDER BY pv.`post_id` DESC
LIMIT 1
EDIT 1 - last GROUP BY pv.post_id was added as per #McAdam331 notice about count() function without GROUP BY
I believe the issue here is mostly as a result of preforming aggregation (using the COUNT()) function, without any group by. Although, it seems like you don't necessarily need it because you want that count only for the post in question.
If you're trying to gather all of that information for a single post, I would adjust your WHERE clause to have a condition to only gather that information for the post with the largest ID.
Instead of ordering by ID and limiting by 1, use a subquery to get the largest id, like this:
...
WHERE pv.status = 1 AND post_data.slug = 'abc' AND pv.post_id = (SELECT MAX(post_id) FROM post_view);

Where clause inside joined select

I'm trying to accommodate a similar solution to this one - what I have is a SELECT query inside a JOIN, and the problem is that the query runs at full for all rows (I'm talking 60,000 rows per table - and it runs on 3 tables!).
So what I want to do, is add a WHERE clause to the SELECTs inside the JOIN.
But, I can't access the outer SELECT and get the proper WHERE condition I need.
The query I'm attempting is here:
SELECT c.compete_id AS id,
s.id AS store_id,
c.enabled AS enabled,
s.store_name AS store_name,
s.store_url AS store_url,
c.verified AS verified,
r.rating_total AS rating,
r.positive_percent AS percent,
r.type AS type
FROM compete_settings c
LEFT JOIN stores s
ON c.compete_id = s.id
LEFT JOIN (
(SELECT store_id, rating_total, positive_percent, 'ebay' AS type FROM ebay_sellers WHERE store_id = c.compete_id)
UNION
(SELECT store_id, rating_total, positive_percent, 'amazon' AS type FROM amazon_sellers WHERE store_id = c.compete_id)
UNION
(SELECT store_id, CASE WHEN rank = 0 THEN NULL ELSE (200000 - rank) END AS rating_total, '100' as positive_percent, 'alexa' AS type FROM alexa_ratings WHERE store_id = c.compete_id)
) AS r
ON c.compete_id = r.store_id
WHERE c.store_id = :store_id
Note, :store_id is a variable bound through the framework - let's imagine it's the number 12345.
How can I do this? Any ideas?
We ended up going witha different approach - we just JOINed everything and only selected the right columns with a CASE. Here's the final query:
SELECT c.id AS id,
s.id AS store_id,
c.enabled AS enabled,
s.store_name AS store_name,
s.store_url AS store_url,
c.verified AS verified,
(CASE WHEN eb.rating_total IS NOT NULL THEN eb.rating_total
WHEN am.rating_total IS NOT NULL THEN am.rating_total
WHEN ax.rank IS NOT NULL THEN ax.rank
END) AS rating,
(CASE WHEN eb.positive_percent IS NOT NULL THEN eb.positive_percent
WHEN am.positive_percent IS NOT NULL THEN am.positive_percent
WHEN ax.rank IS NOT NULL THEN '100'
END) AS percent,
(CASE WHEN eb.positive_percent IS NOT NULL THEN 'ebay'
WHEN am.positive_percent IS NOT NULL THEN 'amazon'
WHEN ax.rank IS NOT NULL THEN 'alexa'
END) AS type
FROM compete_settings c
LEFT JOIN stores s
ON c.compete_id = s.id
LEFT JOIN ebay_sellers eb ON c.compete_id = eb.store_id
LEFT JOIN amazon_sellers am ON c.compete_id = am.store_id
LEFT JOIN alexa_ratings ax ON c.compete_id = ax.store_id
WHERE c.store_id = :store_id