have some problem with getting data in laravel
i have table companies and addresses, want to get all companies which have same address
an example
companies table
id
name
created_at
1
company 1
30/01/2023
2
company 2
30/01/2023
3
company 3
30/01/2023
4
company 4
30/01/2023
addresses table
id
company_id
a1
a2
city
state
1
1
aa1
aa1
cc1
ss1
2
2
aa2
aa2
cc2
ss2
3
3
aa3
aa3
cc3
ss3
4
4
aa1
aa1
cc1
ss1
i need companies with ids 1, 4 because they has same address
id
name
1
company 1
4
company 4
What immediately comes to my head is using a SQL join to achieve this i.e using a SELF JOIN to compare the table with itself while also using subqueries to ensure the address information is available on the tables you're comparing. Please try below query out, should be of help:
SELECT t2.c2_id as id, t2.c2_name as name
FROM (
SELECT
c.id as c1_id, c.name as c1_name,
CONCAT(addresses.a1, ' ', addresses.a2, ' ', addresses.city, ' ', addresses.state) as c1_address
FROM companies c
JOIN addresses
ON c.id = addresses.company_id
) t1,
(
SELECT
c.id as c2_id, c.name as c2_name,
CONCAT(addresses.a1, ' ', addresses.a2, ' ', addresses.city, ' ', addresses.state) as c2_address
FROM companies c
JOIN addresses
ON c.id = addresses.company_id
) as t2
WHERE c1_id <> c2_id
AND c1_address = c2_address;
https://sqlize.online/s/dp
Related
I have a query with more than one table with a lot of criteria that gives this result
select book, max(version)
from a,b
where condition 1, condition 2... and so on
the query is nice , the result is
book
version
book1
3
book2
2
book3
1
I want to join this result with another table c:
book
version
id
book1
1
id1
book1
2
id2
book1
3
id3 -> I want to join the result with this row
book1
4
id4
book2
1
id5
book2
2
id6 -> I want to join the result with this row
book3
1
id7 -> I want to join the result with this row
If you need to join Table A and Table C.
than try below query:
SELECT a.book, max(version) over
( partition by a.book order by a.book) version,c.id
FROM tablea a, tablec c
where a.book.c.book
and a.version=c.version;
Use a sub-query and join:
SELECT m.book,
c.version,
c.id
FROM (
select book,
max(version) AS max_version
from a INNER JOIN b
ON (condition 1)
where condition 2 ... and so one
) m
INNER JOIN c
ON ( m.book = c.book
AND m.max_version = version )
My table 'Details' looks like this,
ID Name City
1 Arun Chennai
2 Arun Mumbai
3 Raj Bangalore
4 Raj Chennai
I want to select the same Name containing different values in 'City' column in a single row.
I have written the below query
select a.id, b.id, a.Name, a.city, b.city
from Details a join Details b on a.Name = b.Name
where a.City <> b.City
For which the output is
id id Name City City
1 2 Arun Chennai Mumbai
2 1 Arun Mumbai Chennai
3 4 Raj Bangalore Chennai
4 3 Raj Chennai Bangalore
But I need the output in one row with both id's and City's
id id Name City City
1 2 Arun Chennai Mumbai
3 4 Raj Bangalore Chennai
Kindly advise
Try this:
select a.id, b.id, a.Name, a.city, b.city
from Details a
inner join Details b on a.Name = b.Name and a.id < b.id
Note: This will work as long as you always have two records per Name. If you have either one, or two records, then you can use LEFT JOIN instead of INNER JOIN.
Edit: If you can have one, two, or three records per Name, then your query can be formulated as follows:
select a.id, b.id, a.Name, a.city, b.city
from Details a
left join Details b on a.Name = b.Name and a.id < b.id
left join Details c on a.Name = c.Name and b.id < c.id
Note: If the number of records varies dynamically then you have to use some sort of grouping with string concatenation, an equivalent of GROUP_CONCAT used in MySQL.
I don't know the reason why you need IDs & Cities of multiple columns in a same set.
But this may help you (Assumed RDBMS : SQL Server)
SELECT NAME, STUFF((
SELECT ',' + City
FROM #DETAILS D2
WHERE D1.NAME = D2.NAME
FOR XML PATH('')
), 1, 1, '') as Cities
FROM #DETAILS D1
GROUP BY NAME
This will give you the result like
+------+-------------------+
| Name | Cities |
+------+-------------------+
| Arun | Chennai,Mumbai |
| Raj | Bangalore,Chennai |
+------+-------------------+
You can replace your table name. Here I have used inner join.
SELECT T1.ID,T2.ID,T1.Name,T1.City,T2.City
FROM your_table T1
INNER JOIN your_table T2
ON T1.ID < t2.ID
WHERE T1.Name = T2.Name
I have two tables
price
--------
id value key
sku1 r1 12
sku1 r2 13
sku2 r1 12
sku3 r1 14
specialprice
-----
id value key startdate enddate
sku2 r2 13 20-Mar 20-May
sku3 r1 15 20-Mar 20-May
I am trying to use LISTAGG function and bring output like:
output
------
skuid value
sku1 r1:12,r2:13
sku2 r2:13
sku3 r1:15
If there is an entry in specialprice table and sysdate is between startdate and enddate then i need to consider that otherwise i need to get value from price table.
In price table a id may have two entries i need to LISTAGG those two records.
specialprice table may not have entry for the id in price table. So i am using FULL OUTER JOIN
PFB Query which i constructed:
SELECT
a.id,
listagg (a.value | | ':' | | nvl (a.key, ' '), ',') WITHIN GROUP (ORDER BY a.value) AS price
FROM price a
FULL OUTER JOIN specialprice b
ON(b.id = a.id)
WHERE sysdate between b.startdate and b.enddate
GROUP BY a.id
but issue is i am not able to get the specialprice table value and key joined.
Please help.
Try this:
select id, listagg(value) within group(order by value) as price
from (
select
p.id,
case when sp.id is not null and sysdate between sp.startdate and sp.enddate
then p.value||':'||p.key
else p.value||':'||p.key
end as value
from price p
left outer join specialprice sp
on p.id = sp.id
)
group by id;
SELECT a.id,listagg (a.value | | ':' | | nvl (a.key, ' '), ',')
WITHIN GROUP (ORDER BY a.value) AS price
FROM price a
LEFT OUTER JOIN specialprice b
ON(b.id = a.id and a.value = b.value and a.key = b.key)
WHERE (sysdate between b.startdate and b.enddate OR b.id IS NULL)
GROUP BY a.id
Based on the requirement explained, if there is a matching id in b it must be current record. If not matching record is found, still a's data must be used. A LEFT OUTER JOIN should be sufficient. Hope this helps.
I have these tables:
Products, Articles, Product_Articles
Lets say, product_ids are: p1 , p2 article_ids are: a1 , a2 , a3
product_articles is:
(p1,a1)
(p1,a2)
(p2,a1)
(p2,a1)
(p2,a2)
(p2,a3)
How to query for product_id, which has only a1,a2, nothing less, nothing more?
UPDATED Try
SELECT p.*
FROM products p JOIN
(
SELECT product_id
FROM product_articles
GROUP BY product_id
HAVING COUNT(*) = SUM(CASE WHEN article_id IN (1, 2) THEN 1 ELSE 0 END)
AND SUM(CASE WHEN article_id IN (1, 2) THEN 1 ELSE 0 END) = 2
) q ON p.product_id = q.product_id
or
SELECT p.*
FROM products p JOIN
(
SELECT product_id, COUNT(*) a_count
FROM product_articles
WHERE article_id IN (1, 2)
GROUP BY product_id
HAVING COUNT(*) = 2
) a ON p.product_id = a.product_id JOIN
(
SELECT product_id, COUNT(*) total_count
FROM product_articles
GROUP BY product_id
) b ON p.product_id = b.product_id
WHERE a.a_count = b.total_count
Here is SQLFiddle demo for both queries
This is an example of a "set-within-sets" subquery. I advocate using aggregation with a having clause for the logic, because this is the most general way to express the relationships.
The idea is that you can count the appearance of the articles within a product (in this case) in a way similar to using a where statement. The code is a bit more complex, but it offers flexibility. In your case, this would be:
select pa.product_id
from product_articles pa
group by pa.product_id
having sum(case when pa.article_id = 'a1' then 1 else 0 end) > 0 and
sum(case when pa.article_id = 'a2' then 1 else 0 end) > 0 and
sum(case when pa.article_id not in ('a1', 'a2') then 1 else 0 end) = 0;
The first two clauses count the appearance of the two articles, making sure that there is at least one occurrence of each. The last counts the number of rows without those two articles, making sure there are none.
You can see how this easily generalizes to more articles. Or to queries where you have "a1" and "a2" but not "a3". Or where you have three of four of specific articles, and so on.
I believe this can be done entirely using relational joins, as follows:
SELECT DISTINCT pa1.PRODUCT_ID
FROM PRODUCT_ARTICLES pa1
INNER JOIN PRODUCT_ARTICLES pa2
ON (pa2.PRODUCT_ID = pa1.PRODUCT_ID)
LEFT OUTER JOIN (SELECT *
FROM PRODUCT_ARTICLES
WHERE ARTICLE_ID NOT IN (1, 2)) pa3
ON (pa3.PRODUCT_ID = pa1.PRODUCT_ID)
WHERE pa1.ARTICLE_ID = 1 AND
pa2.ARTICLE_ID = 2 AND
pa3.PRODUCT_ID IS NULL
SQLFiddle here.
The inner join looks for products associated with the articles we care about (articles 1 and 2 - produces product 1 and 2). The left outer looks for products associated with articles we don't care about (anything article except 1 and 2) and then only accepts products which don't have any unwanted articles (i.e. pa3.PRODUCT_ID IS NULL, indicating that no row from pa3 was joined in).
How can I join two rows have same id to one row
id name
1 abc
1 def
2 a
2 b
I want result like that
id name
1 abc
def
2 a
b
If you just have two rows then the only tricky part is making sure that each row joins only to a different row, and that you do not get the same pair of rows back twice.
I would:
select a.name || chr(10) || b.name
from table_a a join
table_b b on (a.id = b.id and
a.rowid < b.rowid)