I have a table with hierarchical structure like this:
Create Table tbl1
(
AccountID NVARCHAR(100),
ID int,
ParentID int
);
INSERT INTO tbl1
VALUES ('11', 1, Null), ('12', 2, Null), ('13', 3, Null),
('11/11', 4, 1), ('11/12', 5, 1), ('11/111', 6, 1),
('11/11/001', 7, 4), ('11/11/002', 8, 4), ('12/111', 9, 2),
('12/112', 10, 2);
How to get all children of some nodes from tbl1 in tree structure, according to an other table (FilteringTbl) like this:
AccountID
---------
11/11
12
13
In other words I want to create a SQL query to get all children of nodes 11/11 and 12 and 13 from my first table (tbl1) in SQL Server 2008.
Main tables have more than 5000 records. (tbl1 5400 records and filteringtbl 1500 records)
Please help me. Thanks.
;with C
as (
select AccountID,
ID,
ParentID,
0 as [level]
from tbl1
where ID IN (SELECT ID FROM Filteringtbl)
union all
select I.AccountID,
I.ID,
I.ParentID,
C.[level] + 1 as [level]
from tbl1 as I
inner join C on
C.ID = I.ParentID
)
select *
from C
Related
INSERT INTO #PaymentsTable1 VALUES (1, 1, 1, 'CA')
INSERT INTO #PaymentsTable1 VALUES (2, 1, 2, 'MX')
INSERT INTO #PaymentsTable1 VALUES (1, 1, 1, 'CA')
INSERT INTO #PaymentsTable1 VALUES (2, 1, 2, 'GB')
INSERT INTO #PaymentsTable1 VALUES (1, 1, 1, 'CA')
INSERT INTO #PaymentsTable1 VALUES (2, 1, 2, 'IN')
DECLARE #Count INT
SELECT #Count = COUNT(DISTINCT PMJ.CountryCode) FROM #PaymentsTable1 PMJ GROUP BY PMJ.PId
IF (#Count >= 3)
SELECT DISTINCT Pkey, PId, DataId FROM #PaymentsTable1
ELSE
SELECT 0 AS [Pkey], 0 AS [PId], 0 AS [DataId]
I need records which are having different country code >=3
In this scenario, only the 2nd record should return. With this implementation,
what is the logic to come both PId records to come.
Since you didn't include table definition, I assumed that you have columns in following order: PKey, PId, DataId, CountryCode. So in case code doesn't work, you'll need switch order of columns :)
This should solve your problem :)
;with cte as (
select PKey, PId, DataId from #PaymentsTable1
group by PKey, PId, DataId
having Count(distinct CountryCode) >= 3
)
select * from cte
union all
select 0 as PKey, 0 as PId, 0 as DataId where not exists(select * from cte)
I have a simple table
CREATE TABLE `example` (
`id` int(12) NOT NULL,
`food` varchar(250) NOT NULL
);
With the following data
INSERT INTO `example` (`id`, `food`) VALUES
(1, 'apple'),
(2, 'apple'),
(3, 'apple'),
(4, 'apple'),
(5, 'apple'),
(6, 'apple'),
(7, 'apple'),
(8, 'banana'),
(9, 'banana'),
(10, 'potato'),
(11, 'potato'),
(12, 'potato'),
(13, 'banana'),
(14, 'banana'),
(15, 'banana');
I want to get the oldest 10 rows
SELECT *
FROM example
ORDER BY id ASC
LIMIT 10
But I don't want to get more than 5 rows where food has the same value.
My current query receives 7 apple (more than I want), 2 banana, and 1 potato. In the data provided, I'd want to receive 5 apple, 2 banana, and 3 potato.
How can I accomplish this?
Update:
SQL Group BY, Top N Items for each Group is not a duplicate because it involves a different database. In particular, GROUP BY works different in sql-server than it does in MySQL
You can add a count (in reverse) for each food . . . using variables or a correlated subquery. This will use the latter:
select t.*
from (select t.*,
(select count(*) from example t2 where t2.food = t.food and t2.id >= t.id) as seqnum
from example t
) t
where seqnum <= 5
order by id desc
limit 10;
I didn't create the table and test this, but it should give you what you want. Just a different approach than the one above.
Select *
From (Select ID, Food
, Count(Food) Over(Partition By Food Order by ID) as Appearances
From Your_Table) as a
Where a.Appearances <= 5
Order By ID Asc
You can obviously put the limit if you want.
I have two tables myTable and myTable2 in a mysql database:
CREATE TABLE myTable (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
number INT,
version INT,
date DATE
) ENGINE MyISAM;
INSERT INTO myTable
(`id`, `number`, `version`, `date`)
VALUES
(1, '123', '1', '2016-01-12'),
(2, '123', '2', '2016-01-13'),
(3, '124', '1', '2016-01-14'),
(4, '124', '2', '2016-01-15'),
(5, '124', '3', '2016-01-16'),
(6, '125', '1', '2016-01-17')
;
CREATE TABLE myTable2 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
myTable_id INT
) ENGINE MyISAM;
INSERT INTO myTable2
(`id`, `myTable_id`)
VALUES
(1, 1),
(2, 1),
(3, 2),
(4, 2),
(5, 3),
(6, 3),
(7, 4),
(8, 4),
(9, 4),
(10, 5),
(11, 6)
;
The field myTable2.myTable_id is a foreign key of myTable.Id.
I would like to get all the rows from myTable where myTable2.myTable_id = myTable.Id and the value of the field version in myTable is the maximum for every corresponding value for the field number in myTable.
I tried something like this:
SELECT
*
FROM
myTable,
myTable2
WHERE
myTable.version = (SELECT MAX(myTable.version) FROM myTable)
But the above query does not return the correct data. The correct query should output this:
Id number version date
2 123 2 2016-01-13
5 124 3 2016-01-16
6 125 1 2016-01-17
Please help!
One way to do this is to get the max version for each number in myTable in a derived table and join with that:
SELECT DISTINCT
m.*
FROM
myTable m
JOIN
myTable2 m2 ON m.id = m2.myTable_id
JOIN
(
SELECT number, MAX(version) AS max_version
FROM myTable
GROUP BY number
) AS derived_table
ON m.number = derived_table.number
AND m.version = derived_table.max_version
With your sample data this produces a result like this:
id number version date
6 125 1 2016-01-17
5 124 3 2016-01-16
2 123 2 2016-01-13
your Query is logically wrong. Here is the correct one
SELECT
*
FROM
myTable,
myTable2
WHERE
(myTable.version,myTable.number) in
(SELECT MAX(myTable.version),number FROM myTable group by number)
and myTable.id=myTable2.id
Here is the sqlfiddle http://sqlfiddle.com/#!9/74a67/4/0
This is the query posted for the previous edited question
SELECT * FROM myTable
inner join myTable2 on myTable.id = myTable2.mytable_id
WHERE (version, number) in
(SELECT MAX(version), number FROM myTable group by number)
Try this solution with using subquery simply as:
# Selecting desired result..
SELECT t1.id, t1.number, t1.version, t1.date
FROM myTable As t1 JOIN
# subquery to select max version and its corresponding
# number form myTable
(SELECT number, max(version) As max_ver FROM myTable
GROUP BY number
) As t2 ON t1.number = t2.number and t1.version = t2.max_ver
# Now checking for foreign key..
WHERE t1.id IN (SELECT mytable_id FROM myTable2);
Was it helpful..
i have a table follower and following count..
want to get the count of both in one stored procedure.. is it possible to have two select queries with different where condition on same table possible?
CREATE TABLE Table1
([val1] int, [val2] int, [val3] int, [val4] int, other int)
;
INSERT INTO Table1
([val1], [val2], [val3], [val4], other)
VALUES
(1, 26, 13, 1, 1),
(2, 13, 26, 1, 1),
(3, 10, 26, 1, 1),
(4, 26, 13, 1, 1),
(5, 14, 26, 1, 1)
;
MY select queries
(select count(*) as following_count from table1 where val2=26)
(select count(*) as follower_count from table1 where val3=26)
SQL FIDDLE LINK
Why don't you fire both statement using UNION ALL ?
See: http://dev.mysql.com/doc/refman/5.1/de/union.html
SO:
SELECT COUNT(*) AS following_count FROM table1 WHERE val2=26
UNION ALL
SELECT COUNT(*) AS following_count FROM table1 WHERE val3=26
returns two rows with 2 numbers in 1 query.
In two columns do this:
SELECT
(SELECT COUNT(*) AS following_count FROM table1 WHERE val2=26) col1
, (SELECT COUNT(*) AS following_count FROM table1 WHERE val3=26) col2
You could do this:
SELECT
SUM(CASE WHEN val2=26 THEN 1 ELSE 0 END) AS following_count,
SUM(CASE WHEN val3=26 THEN 1 ELSE 0 END) AS follower_count
FROM
table1
Just add semicolon to your statements...
(select count(*) as following_count from table1 where val2=26);
(select count(*) as follower_count from table1 where val3=26);
In MySQL table cardToCard has 1 row each time a credit card balance is transferred from one card to another card.
create table cardToCard (
id int,
dt date,
card_from int,
card_to int,
amount decimal(6,2),
primary key (id)
);
insert into cardToCard values (1, '2014-01-01', 100, 101, 200.00);
insert into cardToCard values (2, '2014-01-01', 101, 102, 200.00);
insert into cardToCard values (3, '2014-01-01', 102, 103, 200.00);
insert into cardToCard values (4, '2014-01-01', 103, 104, 200.00);
insert into cardToCard values (5, '2014-01-01', 104, 100, 200.00);
insert into cardToCard values (6, '2014-01-01', 99, 104, 200.00);
Query which card has been used 3 or more times.
select card, count(*) 'count'
from
(
select card_from 'card', dt
from cardtocard
union all
select card_to 'card', dt
from cardtocard
) d
group by card
having count >= 3
The results are correct. The question is would it be more efficient to write this as a self join?
http://sqlfiddle.com/#!2/420e72/1
Possibly the most efficient way to write this query would be to start with a list of cards and then do:
select c.card,
((select count(*) from cardTocard ctc where ctc.card_from = c.card) +
(select count(*) from cardTocard ctc where ctc.card_to = c.card)
) as cnt
from cards c
having cnt >= 3;
Then, you need two indexes: cardTocard(card_from) and cardTocard(card_to).
This should use the index for the aggregation, which is typically faster than a file sort.
EDIT:
Using the structure that you are using, it can be faster to do aggregation in the subqueries as well as the outer query:
select card, sum(cnt) as cnt
from ((select card_from as car, count(*) as cnt
from cardtocard
group by card_from
) union all
(select card_to as card, count(*) as cnt
from cardtocard
group by card_to
)
) d
group by card
having count >= 3;
This can be faster because the volume of data for the subqueries is smaller than just union'ing them together.