Sql create a table based on a cell value - sql

I have a problem where I have tables that are created based on the date & time, this table is created in a SP that I didn't write. In any event need to get a count of these tables every time they are created.
What I have done so far is create a table that has these names, and added a Count field.
Table looks like this and is called SP.DBO.AUSEMAIL
SourceTable Count
SP.DBO.VIP_BPAU_00030_20130531_092027
SP.DBO.ADV_BPAU_00030_20130531_092027
Now basically I need to create a query that will give me a count of SP.DBO.VIP_BPAU_00030_20130531_092027 and SP.DBO.ADV_BPAU_00030_20130531_092027 and populate the above table.
As I will not know what the table will be called every day, and am working towards fully automating this I can't just to counts of each of these files.
I have tried something like this and am getting nowhere.
select count(*)
from top 1 (select sourcetable
from SP.DBO.AUSEMAIL
where source_table like 'SP.DBO.VIP_BPAU%')
Any ideas would be very helpful.

To update count column in your ausemail table
UPDATE a
SET a.count = i.rowcnt
FROM sysindexes AS i INNER JOIN sysobjects AS o
ON i.id = o.id JOIN ausemail a
ON o.name = a.source_table
If you know exactly the pattern you can do something like this
SELECT o.name source_table,
i.rowcnt count
FROM sysindexes AS i INNER JOIN sysobjects AS o
ON i.id = o.id
WHERE o.name LIKE '___!_BPAU!_%' ESCAPE '!' -- < adjust the pattern as needed
Sample output:
| SOURCE_TABLE | COUNT |
------------------------------------------
| VIP_BPAU_00030_20130531_092027 | 4 |
| ADV_BPAU_00030_20130531_092027 | 2 |
Here is SQLFiddle demo.

Related

Join table using column value as table name

Is it possible to join a table whereby the table name is a value in a column?
Here is a TABLE called food:
id food_name price_table pricing_reference_id
1 | 'apple' | 'daily_price' | 13
2 | 'banana' | 'monthly_price' | 13
3 | 'hotdog' | 'weekly_price' | 17
4 | 'sandwich' | 'monthly_price' | 9
There are three other tables (pricing tables): daily_price, weekly_price, and monthly_price tables.
Side note: Despite their names, the three pricing tables display vastly different kinds of information, which is why the three tables were not merged into one table
Each row in the food table can only be joined with one of the three pricing tables at most.
The following does not work -- it is just to illustrate what I am trying to get at:
SELECT *
FROM food
LEFT JOIN food.price_table ON food.pricing_reference_id = daily_price.id
WHERE id = 1;
Obviously the query does not work. Is there any way that the name of the table in the price_table column could be used as the table name in a join?
I would suggest left joins:
select f.*,
coalesce(dp.price, wp.price, mp.price) as price
from food f left join
daily_price dp
on f.pricing_reference_id = dp.id and
f.pricing_table = 'daily_price' left join
weekly_price wp
on f.pricing_reference_id = wp.id and
f.pricing_table = 'weekly_price' left join
monthly_price mp
on f.pricing_reference_id = mp.id and
f.pricing_table = 'monthly_price' ;
For the columns you reference, you need to use coalesce() to combine the results from the three tables. You say that the tables have different data, so you would need to list the columns separately.
The main reason I recommend this approach is performance. I think the left joins should be faster than any solution that uses union all.
Could you get your expected result using by a derived table with UNION SELECT which has a column of each table name?
SELECT *
FROM food
LEFT JOIN
(
SELECT 'daily_price' AS price_table, * FROM daily_price
UNION ALL SELECT 'monthly_price', * FROM monthly_price
UNION ALL SELECT 'weekly_price', * FROM weekly_price
) t
ON food.price_table = t.price_table AND
food.pricing_reference_id = t.id
ORDER BY food.id;
dbfiddle

Understanding Unnamed Column in SQL Select Statement Results

I am more familiar with a MongoDB architecture than sql. A colleague passed this query to me in order to get some data out of sybase:
SELECT order_items.contracted_rate FROM customers
JOIN orders
ON orders.customers_id = customer.id_number
JOIN order_items
ON order_items.order_id = orders.id,
ORDER by customer.id_number
When I run this query I get data that looks like this:
contracted_rate
1 | 20
2 | 14
3 | 18
My question is, what are the left-side numbers pertaining to from the above query? In other words, how can I map these item numbers (1, 2, 3) to a sybase table?
I'm used to seeing something more like this after running a sybase query:
id contracted_rate
1 | 20
2 | 14
3 | 18
So I'm trying to understand what the unnamed column refers to, and how I can map it to a sybase table to match up the correct customers?
Assuming this is the customerID you need, you can do this. The Id you show is not part of the result set
SELECT customer.id_number, order_items.contracted_rate
FROM customers
JOIN orders
ON orders.customers_id = customer.id_number
JOIN order_items
ON order_items.order_id = orders.id,
ORDER by customer.id_number

Combine multiple row values into one row

I have a result set that should be pulled into a report as one line. However, there can be multiple buyers associated to an order and these buyers are represented as a new row in the database. So for instance, I have the following...
SELECT
O.OrdersID
,BS.LastName
FROM
Orders O
LEFT JOIN
BuyerSeller BS ON O.OrdersID = BS.OrdersID
If there are multiple buyers, it will return the following result set as follows:
OrdersID | LastName
----------------------
1 | Tester1
1 | Tester2
1 | Tester3
I'd like it to return as the following (separated by columns):
OrdersID | LastName
---------------------------------------
1 | Tester1, Tester2, Tester3
Thanks for the assistance.
Here is your Answer.
SELECT DISTINCT Ord.OrderID , substring
((SELECT ',' + BS.LastName AS [text()]
FROM Orders O LEFT JOIN BuyerSeller BS ON O.OrderID = BS.OrderID
ORDER BY O.OrderID FOR XML PATH('')), 2, 1000) LastName
FROM Orders ord
This will return the expected output.
To accomplish this in SSRS you would need to
Create a table with OrdersID as Row group
Make sure there is no detail section inside the group. If there is one delete it without deleting the rows.
Write this experession for LastName:
=Join(Lookupset(Fields!OrdersID.Value, Fields!OrdersID.Value, Fields!LastName.Value, "myDataSet"), ", ")
Remember SSRS is case sensitive.

SQL Joins with 4 tables

I have a problem here and I got a bit confused with outer/inner joins and multiple conditions
We have 4 tables with - columns:
table_cars - id | brand | type | license
table_equipments - id | name | description
table_distances - id_car | date | distance
table_cars_equipments - id_car | id_equipment
First query should show all cars that have equipment "fire extinguisher" and have been driving yesterday.
I have tried to write this query:
SELECT table_cars_equipments.id_car
FROM table_equipments
INNER JOIN table_cars_equipments
ON table_equipments.id = table_cars_equipments.id_equipment
AND table_equipments.name LIKE 'fire extinguisher';
Though I am still confused how to add the cars which had been driving yesterday, I don't know how to make the connection with the table table_distances.
Add another JOIN with the table table_cars and another one to the table table_distances. Then add a condition to the WHERE clause to get only those cars that have been driving yesterday. Something like this:
SELECT
c.id,
c.brand,
c.type,
c.license
ce.id_car,
...
from table_equipments AS e
INNER JOIN table_cars_equipments AS ce ON e.id = ec.id_equipment
INNER JOIN table_cars AS c ON c.id = ce.id_car
INNER JOIN table_distances AS d ON d.id_car = c.id
WHERE e.name LIKE 'fire extinguisher'
AND d.date = ?;
Note that: I used aliases for the table c, e etc, instead of the tables' full names.

Find duplicate Records in MySQL using LIKE

I would like to find all duplicate records by name in a customer table using MySQL including those that do not match exactly.
I know I can use the query
SELECT id, name FROM customer GROUP BY name HAVING count(*) > 1;
to find all rows that match exactly, but I want to find all duplicate rows matching with a LIKE clause. For instance there might be a customer with the name "Mark's Widgets" and another "Mark's Widgets Inc." I would like my query to find these as duplicates. So something along the lines of
SELECT id, name AS name1 ... WHERE name1 LIKE CONCAT("%", name2, "%") ...
I know that's completely incorrect but that's the idea. Here is the able schema:
mysql> describe customer;
+-----------------------------+--------------+------+-----+------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------------+--------------+------+-----+------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(140) | NO | | NULL | |
...
EDIT: To clarify, I want to find all duplicates, not just duplicates of one specific customer name.
It's quite possible to do this, but before you even begin you need to define your rules regarding what is a match and what is not, without that you can't go anywhere.
You could, for example, ignore the first and last 3 characters of the name and match on the middle characters, or you could choose more complex logic, but there is no magic method of achieving what you want, you will have to code the logic. Whatever your choice it needs to be defined before you start and before we can really help much.
No mysql here so excuse the syntax errors ( its t-sql syntax if any) but i'm thinking a self join
SELECT
t1.ID
FROM MyTable t1
LEFT OUTER JOIN MyTable t2
ON t1.name LIKE CONCAT('%', t2.name, '%')
group by t1.ID
HAVING count(*) > 1
I think this will work, but in my experience, having functions inside ONs takes a ridiculous amount of time to process, particularly in combination with the LIKE operator. Still, it's marginally better than a cross join.
SELECT
cust1.id,
cust1.name
FROM
customer AS cust1
INNER JOIN customer AS cust2 ON
(cust1.name LIKE (CONCAT('%',CONCAT(cust2.name,'%'))))
GROUP BY
cust1.id,
cust1.name
HAVING
count(*) > 1
How about this. You can substitute the a.name=b.name with your like if that makes a difference.
Select a.id, b.id from customer a, customer b where a.name = b.name and a.id != b.id;
My answer would be...
SELECT A . *
FROM customer AS A, customer AS B
WHERE A.name LIKE CONCAT( '%', B.name, '%' )
AND A.name = B.name
GROUP BY A.id
HAVING COUNT( * ) >1
SELECT * FROM customer WHERE name LIKE "%Mark's Widgets%";
http://www.mysqltutorial.org/sql-like-mysql.aspx should also help with the LIKE command.
Not sure why you're needing to use the CONCAT section though, so this might be too simple.