How to build the following sql query [closed] - mysql

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions must demonstrate a minimal understanding of the problem being solved. Tell us what you've tried to do, why it didn't work, and how it should work. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have 4 table.
1.Category Table.
Fields : Id , Name , Description
Data : 1 School This is school
2.CategoryMeta Table
Field : Id , CategoryId , FieldName
Data : 1 1 Phone
2 1 Address
3.Object Table
Field : Id , CategoryId , ojectName , ObjectDesc
1 1 ABC School This is a good school
4.ObjectMeta Table
Fields : Id , CategoryId , ObjectId , CategoryMetaId , FieldValue
Data : 1 1 1 1 919475864253
2 1 1 2 ABC Road.India
I want the following output from the query.I set the category Id as a parameter
ObjectId ObjectName ObjectDesc Phone Address
1 ABC School This is a good school 919475864253 ABC Road.India
I need a list of objects.Can any one help me..
Thanks in advance..

You should be able to JOIN the tables and use an aggregate function with a CASE expression to convert the rows of values into columns:
select o.id,
o.ojectname,
o.objectdesc,
max(case when cm.fieldname = 'Phone' then om.fieldvalue end) Phone,
max(case when cm.fieldname = 'Address' then om.fieldvalue end) Address
from object o
left join objectmeta om
on o.id = om.objectid
left join categorymeta cm
on om.categorymetaid = cm.id
group by o.id, o.ojectname, o.objectdesc;
See SQL Fiddle with Demo. Depending on your RDBMS that you are using you could create a dynamic SQL version of this what will get the list of fieldnames based on what is stored in your database.

This is the query, but your schema need some Improvements.
select ph.*, om2.FieldValue as Address from
(
select o.id as ObjectId, o.ObjectName, o.ObjectDesc,om1.FieldValue as Phone
from object o
join ObjectMeta om1 on o.id = om1.ObjectID
where om1.CategoryMetaID = 1
) ph
join ObjectMeta om2 on ph.ObjectId = om2.ObjectID
where om2.CategoryMetaID = 2

Related

A complex SQL query requirement for a table containing data in unusual way [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a bit complex situation for extracting information from a table. I am not sure what is the best way to do it.
I have two tables :
student
student_information
student
id name
-- --------
1 shredder
2 Queen
student_infromation
student_id property value
---------- -------- -----
1 dept CS
1 address DE
1 class X
2 dept MS
2 address DE
2 class IX
Running:
select * from student
join student_information si on student.id = si.student_id
Gives me output like this :
id name student_id property value
-- -------- ---------- -------- -----
1 shredder 1 dept CS
1 shredder 1 address DE
1 shredder 1 class X
2 queen 2 dept MS
2 queen 2 address DE
2 queen 2 class IX
select * from student
join student_information si on student.id = si.student_id
where property in ('dept','class')
I need information just for Dept and Class for each student,but currently the property class and department is listed as row. I want to make column out of it.
Can we construct the table like this?
id name dept class
-- -------- ---------- ------
1 shredder cS X
1 queen MS IX
You may join the two tables and then aggregate by student, turning out the properties you want using pivoting logic:
SELECT
s.id,
s.name,
MAX(CASE WHEN si.property = 'dept' THEN si.value END) AS dept,
MAX(CASE WHEN si.property = 'class' THEN si.value END) AS class
FROM student s
LEFT JOIN student_information si
ON s.id = si.student_id
GROUP BY
s.id,
s.name;
Demo

SQL: How do I SELECT pair of a table objects with limited repetition for each object?

I want to find different pairs of questions but in a way that each question repeats at most a few (like 5 which is not important) times in all of the pairs of the result.
I have a table of questions, and by Cartesian product of it on itself every question in first position repeats at least with all of other questions.
how can I limit the result to find question pairs with a few repetition for each question at of all?
the main table is something like this:
id question
1 q1
2 q2
3 q3
4 q4
with Cartesian product I achieve
id1 question1 id2 question2
1 q1 2 q2
1 q1 3 q3
1 q1 4 q4
.
.
.
but I just want
id1 question1 id2 question2
1 q1 2 q2
3 q3 4 q4
(no more repetition for q1)
thanks in advance
if Id is continue sequence (no holes) you can pair one even id with one odd id.
SELECT *
FROM question Q1
JOIN question Q2
ON Q1.ID = Q2.ID -1
WHERE
Q1.ID % 2 <> 0
now if the number of question is odd you can add one aditional par for example the last question with the first one.
UNION
SELECT *
FROM question Q1
JOIN question Q2
WHERE
Q1.ID = 1
AND Q2.ID = (SELECT max(ID) FROM questions)
You want a small number of random question pairs, a much smaller number than N**2. Compute the Cartesian cross product, randomly shuffle it, and produce the first few rows.
select * from crossproduct order by sha1(qid1 + ',' + qid2) limit 10;
assuming this setup:
drop table if exists posts;
create table posts (
id integer primary key auto_increment,
body varchar(80)
);
drop view if exists crossproduct;
create view crossproduct as
select p1.id as qid1, p1.body as question1,
p2.Id as qid2, p2.Body as question2
from posts p1, posts p2
where p1.id != p2.id
;
To re-shuffle, use sha1(qid1 + ', 1,' + qid2), or , 2,, ....

Group by in complex query with cases [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I have a table:
Visit (FromId, ToId, VisitTime)
where FromId and ToId are FKs to table
UserProfile (uid, name, age ...)
As a user with my UID I want to select all profiles I have visited or who visited me in one result set ordered by VisitTime and with the indication of the "direction of the visit".
I get data using this select:
SELECT CASE WHEN a.FromID = 'yourIDHere'
THEN c.Name
ELSE b.Name
END Name,
CASE WHEN a.FromID = 'yourIDHere'
THEN c.Age
ELSE b.Age
END Age,
a.VisitTime,
CASE WHEN a.FromID = 'yourIDHere'
THEN 'You'
ELSE 'Friend'
END DirectionOfVisit
FROM Visit a
INNER JOIN UserProfile b
ON a.FromID = b.Uid
INNER JOIN UserProfile c
ON a.ToID = c.Uid
WHERE 'yourIDHere' IN (a.FromID, a.ToID)
ORDER BY a.VisitTime
Now it prints (pseudo output)
Jack (id1) | IN |12.12.2012
Jack (id1) | IN |11.12.2012
Jack (id1) | IN |11.12.2012
Jack (id1) | OUT | 13.12.2012
Jack (id1) | OUT | 12.12.2012
Michael (id5) | IN | 5.12.2012
Michael (id5) | OUT | 6.12.2012
Michael (id5) | OUT | 5.12.2012
I would like the list to be like this:
Jack | IN | 12.12.2012 (the most recent)
Jack | OUT | 13.12.2012 (the most recent)
Michael (id5) | IN | 5.12.2012 (the most recent)
Michael (id5) | OUT | 6.12.2012 (the most recent)
I know the GROUP command would solve it but it's too complex for me (beginner).
You could use GROUP BY along with an aggregate function to get the result. Since you want the most recent date for each name and type (IN/OUT), then you can use the max() aggregate function on the date column. You will then use a GROUP BY on the other columns you want to return:
The basic syntax will be:
select
name,
type,
max(date) date
from yourtable
group by name, type;
See SQL Fiddle with Demo
If you want to return the max date with your existing query, you can just expand the query to use:
select name, age, max(VisitTime), DirectionOfVisit
from
(
SELECT CASE WHEN a.FromID = 'yourIDHere'
THEN c.Name
ELSE b.Name
END Name,
CASE WHEN a.FromID = 'yourIDHere'
THEN c.Age
ELSE b.Age
END Age,
a.VisitTime,
CASE WHEN a.FromID = 'yourIDHere'
THEN 'You'
ELSE 'Friend'
END DirectionOfVisit
FROM Visit a
INNER JOIN UserProfile b
ON a.FromID = b.Uid
INNER JOIN UserProfile c
ON a.ToID = c.Uid
WHERE 'yourIDHere' IN (a.FromID, a.ToID)
) d
group by name, age, DirectionOfVisit;
See SQL Fiddle with Demo

select query for multiple chat system [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm making a system of chat similar to facebook, where you can talk with 2 or 3 people in the same time. My issue is on the select the conversation.
inbox_conversation (this table is for create a new id of conversation if the user start to talk the first time)
id_conversation | occured_at
1 13482942
2 18583953
inbox_join (table for user join on the conversation in this case there is user 1, 2, 3 on the disccussion with id 1)
id_conversation | id_user
1 1
1 2
1 3
2 4
2 5
inbox_msg (table for record the message sent)
id_conversation | id_user | message | occured_at
1 1 Hey 1457694
1 2 Hola 3848374
1 3 Cool 3294933
2 4 Wow 4392934
2 5 Yes 9485737
Now i have to do some query for select the messages having just the id_user of the conversation, in this case i have 1,2,3. Someone can help me to build this query please.
Final result that i'm looking for selecting the discussion with id_user 1,2,3
id_user | message | occured_at
1 Hey 1457694
2 Hola 3848374
3 Cool 3294933
PS: if the conversation have 3 users and i try to select just 2 of them i have be able to don't see the conversation.
if I have just the id of the users 1,2 in this case there is no discussion with just that 2 user, but if the user 1 write to user 2 in the database will be another id discussion and will correlate to both user. Like that if i add another user example user 3 he can't see the previous messages sent between user 1 and 2
if is a bad idea select just with id user, i can study some solution for pass the id of discussion.
ok, i did came up with logic for something called "Dataset Comparison" where multiple datasets of multiple rows were getting compared and need to find if any of them are matching.
basic point in this query will be, durig the search we need to make sure that the session we find out has exactly same user by value and by count. (nothing more+nothing less+same value)
DECLARE #inbox_msg TABLE
(
id_conversation INT NOT NULL
,id_user INT NOT NULL
,[message] NVARCHAR(MAX) NULL
,occured_at TIMESTAMP NOT NULL
)
INSERT INTO #inbox_msg
( id_conversation ,
id_user ,
message
)
SELECT 1,1,'Hey'
UNION ALL SELECT 1,2,'Hola'
UNION ALL SELECT 1,3,'Cool'
UNION ALL SELECT 2,4,'Wow'
UNION ALL SELECT 2,5,'Yes'
--this I added to make sure 3 will not become part of your result set.
UNION ALL SELECT 3,1,'Testing'
UNION ALL SELECT 3,2,'Search'
UNION ALL SELECT 3,3,'query'
UNION ALL SELECT 3,4,'Result'
--this is the list of users you want to search for
DECLARE #searchMessgeByUser TABLE
(
id_user INT NOT NULL PRIMARY KEY
)
INSERT INTO #searchMessgeByUser ( id_user )
SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
--find out the sessionID who has exactly same number of user as participant as requested
DECLARE #MatchedSessionID TABLE
(
id_conversation INT NOT NULL
)
INSERT INTO #MatchedSessionID( id_conversation )
SELECT qry.id_conversation
FROM
(
--find out the MatchedSessionIDByUserCount
SELECT id_conversation
FROM #inbox_msg
GROUP BY id_conversation
HAVING (COUNT(DISTINCT id_user) = (SELECT COUNT(1) FROM #searchMessgeByUser) )
INTERSECT
--find out the MatchedSessionIDByUserValue
SELECT id_conversation
FROM #inbox_msg msg
JOIN #searchMessgeByUser usr
ON msg.id_user=usr.id_user
GROUP BY msg.id_conversation
)qry
--final Query
SELECT id_user,message,occured_at
FROM #inbox_msg
WHERE id_conversation IN (SELECT id_conversation FROM #MatchedSessionID)
ORDER BY occured_at
the questions are bit unclear so just making clear what exactly you need?
In the start you mentiuoned that result is queried based on ID_User only.
But in the example last you have is saying "...the result is for DiscussionID 1"
so whihc one is correct? Does DiscussionID and ID-User both available to filter or not?
Also, "PS: if the conversation have 3 users and i try to select just 2 of them i have be able to don't see the conversation"
is that mean id_User filter is of type "WHER ID_USER IN ('','','',)"

Select result from table for matching 2 rows in mysql

I have a MySQL table has these fields
ID, CID, QUESTION, ANSWER, USER
ID is auto increment, every record in table has ID;
CID is point to ID for ANSWER records
For example, we have 4 records, 2 of question 2 of answer, and Mike answers 2 questions
ID CID QUESTION ANSWER USER
1 0 Test NULL John
2 1 NULL This is Test Mike
3 0 Example NULL Tracy
4 3 NULL Yes it is Mike
I want to list questions of which is Mike's answers. How can I match ID and CID fields in same table and print QUESTION for output
I want to list questions of which is Mike's answers.
SELECT t1.*
FROM TableName t1
LEFT JOIN TableName t2 ON t1.ID = t2.CID
WHERE t2.Answer IS NOT NULL
AND t2.User = 'Mike';
SQL fiddle Demo
Note that this gives you the list of questions that Mike has answered therefore you won't find mike listed on them:
ID CID QUESTION ANSWER USER
1 0 Test NULL John
3 0 Example NULL Tracy
select QUESTION from yourtable
where ID in(select ID from yourtable where User = 'Mike' and answer is NOT NULL)