SQL View where rows not mapped - sql-server

Basically what I'm trying to figure out is,
Say I have
table 1tbl1
ID | Name
and table2tbl2
ID | Name
Then I have a mapping table mt
ID | tbl1ID | tbl2ID
Data really isn't important here, and these tables are examples.
How to make a view that will grab all the items in tbl1 that aren't mapped to mt.
I'm using Microsoft SQL-server 2008 by the way.

CREATE VIEW v_unmapped
AS
SELECT *
FROM tbl1
WHERE id NOT IN
(
SELECT tbl1Id
FROM mt
)

Related

How to add data to a single column

I have a question in regards to adding data to a particular column of a table, i had a post yesterday where a user guided me (thanks for that) to what i needed and said an update was the way to go for what i need, but i still can't achieve my goal.
i have two tables, the tables where the information will be added from and the table where the information will be added to, here is an example:
source_table (has only a column called "name_expedient_reviser" that is nvarchar(50))
name_expedient_reviser
kim
randy
phil
cathy
josh
etc.
on the other hand i have the destination table, this one has two columns, one with the ids and the other where the names will be inserted, this column values are null, there are some ids that are going to be used for this.
this is how the other table looks like
dbo_expedient_reviser (has 2 columns, unique_reviser_code numeric PK NOT AI, and name_expedient_reviser who are the users who check expedients this one is set as nvarchar(50)) also this is the way this table is now:
dbo_expedient_reviser
unique_reviser_code | name_expedient_reviser
1 | NULL
2 | NULL
3 | NULL
4 | NULL
5 | NULL
6 | NULL
what i need is the information of the source_table to be inserted into the row name_expedient_reviser, so the result should look like this
dbo_expedient_reviser
unique_reviser_code | name_expedient_reviser
1 | kim
2 | randy
3 | phil
4 | cathy
5 | josh
6 | etc.
how can i pass the information into this table? what do i have to do?.
EDIT
the query i saw that should have worked doesn't update which is this one:
UPDATE dbo_expedient_reviser
SET dbo_expedient_reviser.name_expedient_reviser = source_table.name_expedient_reviser
FROM source_table
JOIN dbo_expedient_reviser ON source_table.name_expedient_reviser = dbo_expedient_reviser.name_expedient_reviser
WHERE dbo_expedient_reviser.name_expedient_reviser IS NULL
the query was supposed to update the information into the table, extracting it from the source_table as long as the row name_expedient_reviser is null which it is but is doesn't work.
Since the Names do not have an Id associated with them I would just use ROW_NUMBER and join on ROW_NUMBER = unique_reviser_code. The only problem is, knowing what rows are null. From what I see, they all appear null. In your data, is this the case or are there names sporadically in the table like 5,17,29...etc? If the name_expedient_reviser is empty in dbo_expedient_reviser you could also truncate the table and insert values directly. Hopefully that unique_reviser_code isn't already linked to other things.
WITH CTE (name_expedient_reviser, unique_reviser_code)
AS
(
SELECT name_expedient_reviser
,ROW_NUMBER() OVER (ORDER BY name_expedient_reviser)
FROM source_table
)
UPDATE er
SET er.name_expedient_reviser = cte.name_expedient_reviser
FROM dbo_expedient_reviser er
JOIN CTE on cte.unique_reviser_code = er.unique_reviser_code
Or Truncate:
Truncate Table dbo_expedient_reviser
INSERT INTO dbo_expedient_reviser (name_expedient_reviser, unique_reviser_code)
SELECT DISTINCT
unique_reviser_code = ROW_NUMBER() OVER (ORDER BY name_expedient_reviser)
,name_expedient_reviser
FROM source_table
it is not posible to INSERT the data into a single column, but to UPDATE and move the data you want is the only way to go in that cases

SQL Server view columns have wrong case

I have a table I am trying to create a view of to work with a new reporting application that needs specific columns. I would think this should be straightforward, but the column names are in the wrong case. Specifically, one column is Customer_ID instead of changing to customer_id as specified in the SQL statement used to create the view.
The original table is: Customer_ID | CustomerAddress | CustomerPhone
The view needs to be: customer_id | customer_address | customer_phone
The view is: Customer_ID | customer_address | customer_phone
The command to create the view is:
BEGIN
SET NOCOUNT ON;
DECLARE #sql_customers nvarchar(max) = 'CREATE VIEW customers AS SELECT
oldcustomers.Customer_ID as customer_id,
oldcustomers.CustomerAddress as customer_address,
oldcustomers.CustomerPhone as customer_phone
FROM oldcustomers'
EXECUTE sp_executesql #sql_customers
END
There's no need to use aliases to change the case unless you're using a case sensitive collation.
The following should do the trick w/o having to jump through hoops...
CREATE VIEW customers
AS
SELECT
oc.customer_id,
oc.customeraddress,
oc.customerphone
FROM
dbo.oldcustomers oc;

Stored procedure using table with recipients

I have a table I would like split and emailed to the corresponding staff member of that department, I have two tables, Table 1 contains all the transaction data against the department and is live, Table 2 is static which essentially lists the staff member who is responsible for the each department.
I need to split up table 1 by Department then lookup the email for the corresponding staff member from table2 and send the split table.
Table 1:
| Customer | ? | Department
| Customer | ? | Department1
| Customer | ? | Department2
Table2:
| Department | Staff | Email
| Department1 | Staff1 | Email
| Department2 | Staff2 | Email
I was wondering, would it be possible to create a stored procedure to do this or would I have to create a subscription in SSRS for each individual staff member?
Thanks,
Neil
I would thoroughly recommend making a simple SSRS report and distributing it via a Data Driven Subscription. The queries below will get you started on your data extracts and you can follow a guide here on how to set up an SSRS Data Driven Subscription.
They are very simple to create, you only need the one subscription to send an email to every Department and they are very easy to maintain, even by someone else with no idea what it does.
declare #t1 table(Cust nvarchar(100)
,Cols nvarchar(100)
,Dept nvarchar(100)
)
declare #t2 table(Dept nvarchar(100)
,Staff nvarchar(100)
,Email nvarchar(100)
)
insert into #t1 Values
('Customer','?','Department1')
,('Customer','?','Department2')
,('Customer','?','Department3')
insert into #t2 Values
('Department1','Staff1','Email1')
,('Department2','Staff2','Email2')
,('Department3','Staff3','Email3')
-- Use this query in your Data Driven Subscription to generate the list of Departments and their respective Emails:
select distinct t1.Dept
,t2.Email
from #t1 t1
left join #t2 t2
on(t1.Dept = t2.Dept)
-- Then use this query in your report to list out the contents of Table 1, matching the #SSRSDeptParameter value in the Data Driven Subscription options.
select t1.Cust
,t1.Cols
,t1.Dept
,t2.Email
from #t1 t1
left join #t2 t2
on(t1.Dept = t2.Dept)
where #t1.Dept = #SSRSDeptParameter

Merging of 2 Tables but different value of fields

I am using MS SQL to create a report to merge 2 tables. The problem is that I need 2 different headers and 1 column needs to have values from 2 different fields from the 2 tables.
Sample
Material | Plant
-------------------------------------------------
Component | Quantity
XXX - Material | ABC--Plant
--------------------------------------------------
YYYY-Component | 3000- Quantity
Is this even possible?
select * from
(
(select *,rn=row_number()over(order by column1) from table1)x,
(select *,rn1=row_number()over(order by column2) from table2)y
)
where x.rn=y.rn1
Firstly you need to give a extra column say rownumber,then repeat same for table2
then you can join using the row_numbers

SQL make rows into columns, PIVOT maybe

I have an MS SQL Server with a database for an E-commerce storefront.
This is some of the tables I have:
Products:
Id | Name | Price
ProductAttributeTypes: -Color, Size, Format
Id | Name
ProductAttributes: --Red, Green, 12x20 cm, Mirrored
Id | ProductAttributeTypeId | Name
Orders:
Id | DateCreated
OrderItems:
Id | OrderId | ProductId
OrderItemsToProductAttributes: --Relates an OrderItem to its product and selected attributes
OrderItemId | ProductAttributeId | ProductAttributeTypeId | ProductId
I want to select from the OrderItems table, to see which items have been purchased.
To see what kind of variants (ProductAtriibutes) was selected, I want those as "dynamic" columns in the resultset.
So the resultset should look like this:
OrderItemId | ProductId | ProductName | Color | Size | Format
1234 123 Mount. Bike Red 2x20 Mirror
I don't know if PIVOT is the thing to use? I'm not using any aggregate functions, so I guess not...
Is there any SQL Ninjas that can help me out?
If you are using sql2005 or 2008 you can use the pivot command. See here.
In the example below the OrderAttributes set will look like:
OrderItemId AttName AttValue
----- ------ -----
100 Color Red
100 Size Small
101 Color Blue
101 Size Small
102 Color Red
102 Size Small
103 Color Blue
103 Size Large
The final results after the PIVOT will be:
OrderItemId Size Color
----- ------ -----
100 Small Red
101 Small Blue
102 Small Red
103 Large Blue
WITH OrderAttributes(OrderItemId, AttName, AttValue)
AS (
SELECT
OrderItemId,
pat.Name AS AttName,
pa.Name AS AttValue
FROM OrderItemsToProductAttributes x
INNER JOIN ProductAttributes pa
ON x.ProductAttributeId = pa.id
INNER JOIN ProductAttributeTypes pat
ON pa.ProductAttributeTypeId = pat.Id
)
SELECT AttrPivot.OrderItemId,
[Size] AS [Size],
[Color] AS Color
FROM OrderAttributes
PIVOT (
MAX([AttValue])
FOR [AttName] IN ([Color],[Size])
) AS AttrPivot
ORDER BY AttrPivot.OrderItemId
There is a way to dynamically build the columns (i.e. the Color and Size columns), as can be seen here. Make sure your database compatibility level on your database is set to something greater than 2000 or you will get strange errors.
In the past, I've created physical tables for read purposes only. The structure you have above is GREAT for storage, but terrible for reporting.
So you could do the following:
Write a script (that is scheduled nightly) or a trigger (on data change) that does the following tasks:
First, you would dynamically go through each Product and build a static table "Product_[ProductName]"
Then go through each ProductAttributeTypes for each product and create/update/delete a physical column on the corresponding Product table.
Then, fill that table with the proper values based on OrderItemsToProductAttributes and ProductAttributes
This is just a rough idea. Make sure you are storing OrderID in the "Static"/"Flattened" tables. And make sure you do everything else you need to do. But after that, you should be able to start pulling from those flattened tables to get the data you need.
Pivot is your best bet, but what I did for reporting purposes, and to make it work well with SSIS is to create a view, which then has this query:
SELECT [InputSetID], [InputSetName], CAST([470] AS int) AS [Created By], CAST([480] AS datetime) AS [Created], CAST([479] AS int) AS [Updated By], CAST([460] AS datetime)
AS [Updated]
FROM (SELECT st.InputSetID, st.InputSetName, avt.InputSetID AS avtID, avt.AttributeID, avt.Value
FROM app.InputSetAttributeValue avt JOIN
app.InputSets st ON avt.InputSetID = st.InputSetID) AS p PIVOT (MAX(Value) FOR AttributeID IN ([470], [480], [479], [460])) AS pvt
Then I can just interact with the view, but, I have a trigger on the table that any new dynamic attributes must be added to, which recreates this view, so I can assume the view is always correct.

Resources