I am looking to get all values from first table along with joinned values from second table.
Table 1 is fee_category with fields:
id | Category
1 | A
2 | B
3 | C
4 | D
Table 2 is fee_charge with fields:
id | std_id | particularID | CategoryID | assign | amount
1 | 1 | 1 | 1 | 0 | 1000
2 | 1 | 1 | 2 | 1 | 12000
3 | 1 | 2 | 3 | 0 | 3000
4 | 1 | 2 | 4 | 0 | 10
5 | 2 | 1 | 2 | 0 | 100
6 | 2 | 2 | 3 | 0 | 120
Base table is "fee_category" from which I need all values left joining with "fee_charge" from where I need values or NULL for a particular std_id and particularID
SELECT fee_category.id, fee_category.Category, fee_charge.std_id
, fee_charge.particularID, fee_charge.CategoryID, fee_charge.assign, fee_charge.amount FROM fee_category
LEFT join fee_charge on fee_category.id=fee_charge.CategoryID
where (fee_charge.std_id = 1 OR fee_charge.std_id IS NULL)
AND (fee_charge.particularID = 1 OR fee_charge.particularID IS NULL)
group By fee_category.id
order By fee_charge.assign DESC
Here I am trying to get all categories of std_id=1 and particularID=1
Correct result should be
id | Category | std_id | particularID | CategoryID | assign | amount
1 | A | 1 | 1 | 1 | 0 | 1000
1 | B | 1 | 1 | 2 | 1 | 12000
1 | C | 1 | NULL | NULL | NULL | NULL
1 | D | 1 | NULL | NULL | NULL | NULL
I am trying various versions of the above query but not getting proper result. Please help
SELECT fee_category.id
, fee_category.Category
, X.std_id
, X.particularID
, X.CategoryID
, X.assign
, X.amount
FROM fee_category
LEFT JOIN
(SELECT * FROM fee_charge
WHERE fee_charge.std_id = 1
AND fee_charge.particularID = 1) AS X
ON x.CategoryID = fee_category.id
It's very hard to follow when the fiddle doesn't match the question, so I may have misunderstood, but perhaps you're after something like this...
SELECT x.id
, z.category
, x.std_id
, y.particularID
, y.categoryID
, y.assign
, y.amount
FROM fee_charge x
LEFT
JOIN fee_charge y
ON y.id = x.id
AND y.particularID = 1
JOIN fee_category z
ON z.id = x.categoryID
WHERE x.std_id = 1;
Related
I have a mysql table that Im trying to run a single/nested query on.
SELECT
`subscriber_id`,
(SELECT...?) AS total_campaigns,
(SELECT...?) AS total_opens,
(total_opens / total_campaigns) as percentage
FROM
`campaigns_table`
The type column with a value = 2 shows that the campaign was opened.
Im looking to return a result set with all subscriber_id's that has the total campaigns and total opens
Query Result Data
+---------------+-----------------+-------------+------------+
| subscriber_id | total_campaigns | total_opens | percentage |
+---------------+-----------------+-------------+------------+
| 1 | 2 | 1 | 0.5 |
| 2 | 2 | 2 | 1.0 |
| 3 | 2 | 0 | 0.0 |
| 4 | 1 | 0 | 0.0 |
| 5 | 1 | 1 | 1.0 |
+---------------+-----------------+-------------+------------+
subscriber_id 1 would be total_campaigns = 2 ( campaign_id's 37428,37239 ) and total_opens = 1 ( only campaign_id 27428 has a type 2 record )
Example Table Data
+---------------+-------------+------------+-------+------+---------+
| subscriber_id | campaign_id | timestamp | count | type | link_id |
+---------------+-------------+------------+-------+------+---------+
| 1 | 37428 | 1434513738 | 1 | 1 | 0 |
| 1 | 37428 | 1434513758 | 1 | 1 | 0 |
| 1 | 37428 | 1434513338 | 2 | 2 | 0 |
| 1 | 37429 | 1434511738 | 1 | 1 | 0 |
| 1 | 37429 | 1434311738 | 1 | 1 | 1 |
| 2 | 37428 | 1534513738 | 1 | 1 | 0 |
| 2 | 37428 | 1534513758 | 1 | 1 | 0 |
| 2 | 37428 | 1534513338 | 2 | 2 | 0 |
| 2 | 37429 | 1534511738 | 1 | 1 | 1 |
| 2 | 37429 | 1534311738 | 1 | 2 | 0 |
| 3 | 37428 | 1534513738 | 1 | 1 | 0 |
| 3 | 37429 | 1534511738 | 1 | 1 | 1 |
| 4 | 57428 | 1534513738 | 1 | 1 | 0 |
| 4 | 57428 | 1534513758 | 1 | 1 | 0 |
| 5 | 57428 | 1534513338 | 3 | 2 | 0 |
+---------------+-------------+------------+-------+------+---------+
Using the answer from #spencer7593 below. How can I then use the results to update another table?
trying to do something like this (it doesn't work how I have it)
UPDATE `subscribers` a
LEFT JOIN `campaigns_table` b ON a.`ID` = b.`subscriber_id`
SET a.`STATUS` = 2
FROM(
SELECT t.subscriber_id
, COUNT(DISTINCT t.campaign_id) AS total_campaigns
, COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL)) AS open_campaigns
, COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL))
/ COUNT(DISTINCT t.campaign_id) AS percentage
FROM `campaigns_table` t
GROUP BY t.subscriber_id
HAVING COUNT(DISTINCT t.campaign_id) > 5 AND COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL)) = 0
ORDER BY t.subscriber_id
) i
It looks to me like a problem that can be addressed with conditional aggregation, with a single pass through the table, with no need for any nested queries.
SELECT t.subscriber_id
, COUNT(DISTINCT t.campaign_id) AS total_campaigns
, COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL)) AS open_campaigns
, COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL))
/ COUNT(DISTINCT t.campaign_id) AS percentage
FROM `campaigns_table` t
GROUP BY t.subscriber_id
ORDER BY t.subscriber_id
It is possible to generate an equivalent result with nested queries, but in general, a single pass through the table (with a single SELECT) will have a more efficient access plan.
If there's a requirement to use nested queries (I don't understand why there would be), in general, I'd prefer to use inline views over correlated queries in the SELECT list.
SELECT q.subscriber_id
, SUM(1) AS total_campaigns
, SUM(q.open_campaign) AS open_campaigns
, SUM(q.open_campaign)/SUM(1) AS percentage
FROM ( SELECT t.subscriber_id
, t.campaign
, MAX(t.type=2) AS `open_campaign`
FROM `campaigns_table` t
WHERE t.campaign IS NOT NULL
GROUP
BY t.subscriber_id
, t.campaign
) q
ORDER BY q.subscriber
If we want to use nested queries in the SELECT list, those would be correlated subqueries...
SELECT s.subscriber
, ( SELECT COUNT(DISTINCT t.campaign)
FROM `campaigns_table` t
WHERE t.subscriber = s.subscriber
) AS total_campaigns
, ( SELECT COUNT(DISTINCT o.campaign)
FROM `campaigns_table` o
WHERE o.subscriber = s.subscriber
AND o.type=2
) AS open_campaigns
, ( SELECT COUNT(DISTINCT po.campaign)
FROM `campaigns_table` po
WHERE po.subscriber = s.subscriber
AND po.type=2
)
/ ( SELECT COUNT(DISTINCT pt.campaign)
FROM `campaigns_table` pt
WHERE pt.subscriber = s.subscriber
) AS percentage
FROM ( SELECT r.subscriber
FROM `campaigns_table` r
GROUP BY r.subscriber
) s
ORDER BY s.subscriber
I have table it store hierarchy data in MySQL this table store stable relation but if each user less than 1000 buy removed and user User a lower level replace this is my code and work fine, after GROUP BY it contain all ancestor of descendant with compare then COUNT(*) AS level count level each user. This I have SQL code to compress data According to minimum buy for each user
+-------------+---------------+-------------+
| ancestor_id | descendant_id | path_length |
+-------------+---------------+-------------+
| 1 | 1 | 0 |
| 1 | 2 | 1 |
| 1 | 3 | 1 |
| 1 | 4 | 2 |
| 1 | 5 | 3 |
| 1 | 6 | 4 |
| 2 | 2 | 0 |
| 2 | 4 | 1 |
| 2 | 5 | 2 |
| 2 | 6 | 3 |
| 3 | 3 | 0 |
| 4 | 4 | 0 |
| 4 | 5 | 1 |
| 4 | 6 | 2 |
| 5 | 5 | 0 |
| 5 | 6 | 1 |
| 6 | 6 | 0 |
+-------------+---------------+-------------+
This is table buy
+--------+--------+
| userid | amount |
+--------+--------+
| 2 | 2000 |
| 4 | 6000 |
| 6 | 7000 |
| 1 | 7000 |
SQL code
SELECT a.*
FROM
( SELECT userid
FROM webineh_user_buys
GROUP BY userid
HAVING SUM(amount) >= 1000
) AS buys_d
JOIN
webineh_prefix_nodes_paths AS a
ON a.descendant_id = buys_d.userid
JOIN
(
SELECT userid
FROM webineh_user_buys
GROUP BY userid
HAVING SUM(amount) >= 1000
) AS buys_a on (a.ancestor_id = buys_a.userid )
JOIN
( SELECT descendant_id
, MAX(path_length) path_length
FROM webineh_prefix_nodes_paths
where a.ancestor_id = ancestor_id
GROUP
BY descendant_id
) b
ON b.descendant_id = a.descendant_id
AND b.path_length = a.path_length
GROUP BY a.descendant_id, a.ancestor_id
I need get max path_length where ancestor_id have At least 1000 amount buy but have error in where in subquery where a.ancestor_id = ancestor_id error code
1054 - Unknown column 'a.ancestor_id' in 'where clause'
I add SQLFidle demo.
You could use this query:
select m.userid as descendant,
p.ancestor_id,
p.path_length
from (
select b1.userid,
min(case when b2.amount >= 1000
then p.path_length
end) as path_length
from (select userid, sum(amount) amount
from webineh_user_buys
group by userid
having sum(amount) >= 1000
) as b1
left join webineh_prefix_nodes_paths p
on p.descendant_id = b1.userid
and p.path_length > 0
left join (select userid, sum(amount) amount
from webineh_user_buys
group by userid) as b2
on p.ancestor_id = b2.userid
group by b1.userid
) as m
left join webineh_prefix_nodes_paths p
on p.descendant_id = m.userid
and p.path_length = m.path_length
order by m.userid
Output for sample data in the question:
| userid | ancestor_id | path_length |
|--------|-------------|-------------|
| 1 | (null) | (null) |
| 2 | 1 | 1 |
| 4 | 2 | 1 |
| 6 | 4 | 2 |
SQL fiddle
Hi I have doubt in sql server
dept
+---------+--------+
| deptkey | deptno |
+---------+--------+
| 1 | 100 |
| 2 | 101 |
| 3 | -1 |
+---------+--------+
loc
+--------+-------+
| lockey | locid |
+--------+-------+
| 1 | 200 |
| 2 | 201 |
| 3 | -1 |
+--------+-------+
trans
+----+--------+-------+------+
| id | deptno | locid | Name |
+----+--------+-------+------+
| 1 | 100 | 201 | abc |
| 2 | 101 | 203 | def |
| 3 | 103 | 200 | rav |
| 4 | 105 | 204 | jai |
| 1 | 101 | 200 | kal |
| 4 | 100 | 206 | lo |
+----+--------+-------+------+
here tran deptno= dept.deptno then corresponding key values bring if not match then we need to unmatched deptno assign -1 and corresponding key need to retrive
similar tran locid=loc.locid
based on above tables I want output like below
+----+------+---------+--------+
| id | Name | deptkey | lockey |
+----+------+---------+--------+
| 1 | abc | 1 | 2 |
| 2 | def | 2 | 3 |
| 3 | rav | 3 | 1 |
| 4 | jai | 3 | 3 |
| 1 | kal | 2 | 1 |
| 4 | lo | 1 | 3 |
+----+------+---------+--------+
I tried like below query
SELECT a.[id],a.name ,b.deptkey,c.lockey
FROM [trans] a left join dept b on a.deptno=b.deptno
left join loc c on a.locid=c.locid
above query not given expected result can you please tell me how to write query to achive this task in sql server
SELECT a.[id],a.name ,
(CASE WHEN b.deptkey IS NULL THEN (select deptkey from DEPT WHERE DeptNo = -1)
ELSE b.deptkey END) AS 'deptkey',
(CASE WHEN c.lockey IS NULL THEN (select LocKey from LOC WHERE LocId = -1)
ELSE c.lockey END) AS 'lockey '
FROM [trans] a left join dept b on a.deptno=b.deptno
left join loc c on a.locid=c.locid
http://www.sqlfiddle.com/#!3/389463/2
SELECT a.[id],a.name ,b.deptkey,c.lockey
FROM [trans] a left join dept b on isnull(a.deptno,-1)=isnull(b.deptno,-1)
left join loc c on a.locid=c.locid
try with this...
SELECT
a.[id]
, a.name
, ISNULL(b.deptkey,-1) AS [deptkey]
, ISNULL(b.lockey,-1) AS [lockey]
FROM [trans] a
left join dept b
on a.deptno = b.deptno
left join loc c
on a.locid = c.locid
When the value is not found ISNULL, change the result to -1 instead of NULL. You can just change the -1 with any default value you prefer as unmatched.
OR if you want a query driven default value (get the last record as the default value). You can change your script as presented below.
SELECT
a.[id]
, a.name
, ISNULL(b.deptkey,(SELECT TOP 1 deptno from dept ORDER BY deptkey DESC)) AS [deptkey]
, ISNULL(b.lockey,(SELECT TOP 1 locid from loc ORDER BY lockey DESC)) AS [lockey]
FROM [trans] a
left join dept b
on a.deptno = b.deptno
left join loc c
on a.locid = c.locid
I have two tables.
I want to select 1 record from first table if
condition is true in second table (active = 0)
table Lead:
-------------
| id | name |
-------------
| 1 | abc1 |
| 2 | abc2 |
| 3 | abc3 |
| 4 | abc4 |
| 5 | abc5 |
-------------
table LeadsDetails:
-------------------------
| id | lead_id | active |
-------------------------
| 1 | 1 | 1 |
| 2 | 1 | 0 |
| 3 | 2 | 0 |
| 4 | 3 | 1 |
| 5 | 4 | 0 |
| 6 | 5 | 0 |
| 7 | 5 | 0 |
--------------------------
expected output:
--------------
| id | name |
--------------
| 2 | abc2 |
| 4 | abc4 |
| 5 | abc5 |
--------------
SELECT `Lead`.`id`, `Lead`.`name`, `Lead`.`unsubscribe`
FROM `leads` AS `Lead` inner JOIN `LeadsDetails` AS `LeadsDetails`
ON (`LeadsDetails`.`lead_id` = `Lead`.`id`)
WHERE `LeadsDetails`.`active` = 0
This should run faster than not exists because the subquery won't run for every row; in this case I'm counting the number of situations where the active field value on table leadsdetails is not 0, for the given ID, and showing only rows where that count is 0 (ie. for the given id the active field is ALWAYS 0)
select l.id, l.name
from lead l
join leadsdetails ld
on l.id = ld.lead_id
group by l.id, l.name
having sum(case when ld.active <> 0 then 1 else 0 end) = 0
Fiddle: http://www.sqlfiddle.com/#!2/00970/2/0
As you need to get the records only when active column doesn't have 1
use NOT EXISTS
SQL FIDDLE DEMO : http://www.sqlfiddle.com/#!2/00970/1
SELECT * FROM
Lead L
WHERE NOT EXISTS (
SELECT 1 FROM LeasdDetails LD
where L.id = LD.lead_id
AND LD.active =1
)
I think you can do what you want with an exists clause:
select l.*
from Lead l
where exists (select 1 from LeadsDetails ld where ld.lead_id = l.id and ld.active = 0)
I have the following problem in MySQL 5.5. Here's my table.
Suppose i have a table With 'Names' with columns Rank,NAME and data in table
When i run the query it will give result as
select *from name
Rank | NAME
-------------
1 | A
1 | B
1 | C
2 | D
2 | E
2 | F
3 | G
3 | H
3 | I
Now this is of course a terribly inconvenient way to organize data, but that's how the data happened to come in (and will continue to come in).
I need to be able to throw at it a way with list of NAMES corresponding to their Respective Rank as shown below
Rank | Name | Name | Name
-----------------------------------
1 | A | B | C
2 | D | E | F
3 | G | H | I
I have query like
select
case when rank=1 then name else null end as 1,
case when rank=2 then name else null end as 2,
case when rank=3 then name else null end as 3
from name
The name with same ranks need to be brought and showed in the same row.i cant estimate the last rank will obtained by the student so i cant pass rank values manually by using 'IN' operator.Since the rank values are unpredictable i need to get them in cross tab view dynamically withh respective to their ranks.
I've tried with all kinds of dynamic crosstab-generating queries (yes, I've seen them all), but I don't have Any sucess. Please help me. Thank you!
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(rank INT NOT NULL
,name CHAR(1) NOT NULL
,PRIMARY KEY(rank,name)
);
INSERT INTO my_table VALUES
(1 ,'A'),
(1 ,'B'),
(1 ,'C'),
(2 ,'D'),
(2 ,'E'),
(2 ,'F'),
(3 ,'G'),
(3 ,'H'),
(3 ,'I');
SELECT * FROM my_table;
+------+------+
| rank | name |
+------+------+
| 1 | A |
| 1 | B |
| 1 | C |
| 2 | D |
| 2 | E |
| 2 | F |
| 3 | G |
| 3 | H |
| 3 | I |
+------+------+
SELECT x.*,COUNT(*) subrank FROM my_table x JOIN my_table y ON y.rank = x.rank AND y.name <= x.name GROUP BY x.rank,x.name;
+------+------+---------+
| rank | name | subrank |
+------+------+---------+
| 1 | A | 1 |
| 1 | B | 2 |
| 1 | C | 3 |
| 2 | D | 1 |
| 2 | E | 2 |
| 2 | F | 3 |
| 3 | G | 1 |
| 3 | H | 2 |
| 3 | I | 3 |
+------+------+---------+
SELECT rank
, MAX(CASE WHEN subrank = 1 THEN name END) name1
, MAX(CASE WHEN subrank = 2 THEN name END) name2
, MAX(CASE WHEN subrank = 3 THEN name END) name3
FROM
( SELECT x.*
, COUNT(*) subrank
FROM my_table x
JOIN my_table y
ON y.rank = x.rank
AND y.name <= x.name
GROUP
BY x.rank
, x.name
) a
GROUP
BY rank;
+------+-------+-------+-------+
| rank | name1 | name2 | name3 |
+------+-------+-------+-------+
| 1 | A | B | C |
| 2 | D | E | F |
| 3 | G | H | I |
+------+-------+-------+-------+