I want to filters 2 Row that contains Null in each row
It is possible to get rid the Null value in 2 Row or More ?
I want to remove Null value in 2 Row. but let the value Null if in 1 row contains Value.
Thanks for your help.
Target
Existing
Null
Null
Null
Phone A
So the data only like this
Target
Existing
Null
Phone B
Phone B
Phone C
I Tried Filter chart but only work in 1 Column.
I've written an Oracle DB Conversion Script that transfers Data from a previous singular table into a new DB with a main table and several child/reference/maintenance tables. Naturally, this more standardized layout (previous could have, say Bob/Storage Room/Ceiling as the [Location] value) has more fields than the old table and thus cannot be exactly converted over.
For the moment, I have inserted a record value (ex.) [NO_CONVERSION_DATA] into each of my child tables. For my main table, I need to set (ex.) [Color_ID] to 22, [Type_ID] to 57 since there is no explicit conversion for these new fields (annually, all of these records are updated, and after the next update all records will exist with proper field values whereupon the placeholder value/record [NO_CONVERSION_DATA] will be removed from the child tables).
I also similarly need to set [Status_Id] something like the following (not working):
INSERT INTO TABLE1 (STATUS_ID)
VALUES
-- Status was not set as Recycled, Disposed, etc. during Conversion
IF STATUS_ID IS NULL THEN
(CASE
-- [Owner] field has a value, set ID to 2 (Assigned)
WHEN RTRIM(LTRIM(OWNER)) IS NOT NULL THEN 2
-- [Owner] field has no value, set ID to 1 (Available)
WHEN RTRIM(LTRIM(OWNER)) IS NULL THEN 1
END as Status)
Can anyone more experienced with Oracle & PL/SQL assist with the syntax/layout for what I'm trying to do here?
Ok, I figured out how to set the 2 specific columns to the same value for all rows:
UPDATE TABLE1
SET COLOR_ID = 24;
UPDATE INV_ASSETSTEST
SET TYPE_ID = 20;
I'm still trying to figure out setting the STATUS_ID based upon the value in the [OWNER] field being NULL/NOT NULL. Coco's solution below looked good at first glace (regarding his comment, not the solution posted, itself), but the below causes each of my NON-NULLABLE columns to flag and the statement will not execute:
INSERT INTO TABLE1(STATUS_ID)
SELECT CASE
WHEN STATUS_ID IS NULL THEN
CASE
WHEN TRIM(OWNER) IS NULL THEN 1
WHEN TRIM(OWNER) IS NOT NULL THEN 2
END
END FROM TABLE1;
I've tried piecing a similar UPDATE statement together, but so far no luck.
Try with this
INSERT INTO TABLE1 (STATUS_ID)
VALUES
(
case
when TATUS_ID IS NULL THEN
(CASE
-- [Owner] field has a value, set ID to 2 (Assigned)
WHEN RTRIM(LTRIM(OWNER)) IS NOT NULL THEN 2
-- [Owner] field has no value, set ID to 1 (Available)
WHEN RTRIM(LTRIM(OWNER)) IS NULL THEN 1
END )
end);
We have a situation where we have a column called Customer_Number in multiple tables. This column is identity column in all the tables, but is there a way that I can make this column unique among all the tables.
for example if I add a row in table_one and identity column assigns it value 1 now if someone add another row in Customer_Number column of table_two , table_three or table_four it should be assigned 2.
how can I do this, I have been reading online and it seems I have to create a table to keep record of the last generated value for any of the table and get MAX() of values from that table and add 1 to it to get the next available value, is there a simpler way of doing this?
I have not used it myself but I think you need the new Sequence Object
You would Create a Sequence Object and rather then using Identity values just get the next value from your sequence object.
Create Sequence Object
CREATE SEQUENCE Sqnc_Number_Generator AS INT --<-- This can be Bigint as well
START WITH 1 -- Start with value 1
INCREMENT BY 1 -- Increment with value 1
MINVALUE 1 -- Minimum value to start is 1
MAXVALUE 50000 -- Maximum it can go to 5000
NO CYCLE -- Do not go above 5000
CACHE 500 -- Increment 500 values in memory rather than incrementing from IO
Getting Next value
SELECT NEXT VALUE FOR dbo.Sqnc_Number_Generator AS NxtValue;
SQL FIDDLE
I have a table named Books which contains some columns.
ColumnNames: BookId, BookName, BookDesc, xxx
I want to track changes for certain columns. I don't have to maintain history of old value and new value. I just want to track that value is changed or not.
What is the best way to achieve this?
1) Create Books table as:
ColumnNames: BookId, BookName, BookName_Changed_Flag, BookDesc, BookDesc_Changed_Flag,
xxx, xxx_Changed_Flag?
2) Create a separate table Books_Change_Log exactly like Books table but only with track change columns as:
ColumnNames: BookId, BookName_Changed_Flag, BookDesc_Changed_Flag, xxx_Changed_Flag?
Please advise.
--Update--
There are more than 20 columns in each table. And each column represents a certain element in UI. If a column value is ever changed from its original record, i need to display the UI element that represents the column value in different style. Rest of the elements should appear normal.
How to use a bitfield in TSQL (for updates and reads)
Set the bitfield to default to 0 at start (meaning no changes) you should use type int for up to 32 bits of data and bigint for up to 64 bits of data.
To set a bit in a bit field use the | (bit OR operator) in the update statement, for example
UPDATE table
SET field1 = 'new value', bitfield = bitfield | 1
UPDATE table
SET field2 = 'new value', bitfield = bitfield | 2
etc for each field use the 2 to power of N-1 for the value after the |
To read a bit field use & (bit AND operator) and see if it is true, for example
SELECT field1, field2,
CASE WHEN (bitfield & 1) = 1 THEN 'field1 mod' ELSE 'field1 same' END,
CASE WHEN (bitfield & 2) = 2 THEN 'field2 mod' ELSE 'field2 same' END
FROM table
note I would probably not use text since this will be used by an application, something like this will work
SELECT field1, field2,
CASE WHEN (bitfield & 1) = 1 THEN 1 ELSE 0 END AS [field1flag],
CASE WHEN (bitfield & 2) = 2 THEN 1 ELSE 0 END AS [field2flag]
FROM table
or you can use != 0 above to make it simple as I did in my test below
Have to actually test to not have errors, click for the test script
original answer:
If you have less than 16 columns in your table you could store the "flags" as an integer then use the bit flag method to indicate the columns that changed. Just ignore or don't bother marking the ones that you don't care about.
Thus if flagfield BOOLEAN AND 2^N is true it indicates that the Nth field changed.
Or an example for max of N = 2
0 - nothing has changed (all bits 0)
1 - field 1 changed (first bit 1)
2 - field 2 changed (second bit 1)
3 - field 1+2 changed (first and second bit 1)
see this link for a better definition: http://en.wikipedia.org/wiki/Bit_field
I know you said you don't need it, but sometimes it's just easier to use something off the shelf which does everything, like: http://autoaudit.codeplex.com/
This just adds a few columns to your table and is not nearly as invasive as either of your proposed schemas, and the trigger necessary to track the changes are also generated by the tool.
You should have a log table that stores the BookId and the date of the change (you don't need those other columns - as you stated, you don't need the old and new values, and you can always get the current value for name, description etc. from the Books table, no reason to store it twice). Unless you are only interested in the last time it changed. You can populate the log table with a simple for update trigger on the books table. For example with the new information you've provided:
CREATE TABLE dbo.BookLog
(
BookID INT PRIMARY KEY,
NameHasChanged BIT NOT NULL DEFAULT 0,
DescriptionHasChanged BIT NOT NULL DEFAULT 0
--, ... 18 more columns
);
CREATE TRIGGER dbo.CreateBook
ON dbo.Books FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.BookLog(BookID) SELECT BookID FROM inserted;
END
GO
CREATE TRIGGER dbo.ModifyBook
ON dbo.Books FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE t SET
t.NameChanged = CASE WHEN i.name <> d.name
THEN 1 ELSE t.NameChanged END,
t.DescriptionChanged = CASE WHEN i.description <> d.description
THEN 1 ELSE t.DescriptionChanged END,
--, 18 more of these assuming all can be compared with simple <> ...
FROM dbo.BookLog AS t
INNER JOIN inserted AS i ON i.BookID = t.BookID
INNER JOIN deleted AS d ON d.BookID = i.BookID;
END
GO
I can guarantee you that after you deliver this solution, one of the next requests is going to be "show me what it was before". Just go ahead and have a history table. That will solve your current problem AND your future problem. It is a pretty standard design on non-trivial systems.
Put two datetime columns in your table, "created_at" and "updated_at". Default both to current_timestamp. Only ever set the value of updated_at if you are changing the data in the row. You can enforce this with a trigger on the table that checks to see if any of the column values are changing, and then updates "updated_at" if so.
When you want to check if a row has ever changed, just check if updated_at > created_at.
I need to search in a table for items which have all of my desired values in a column i.e.
I have table :
ID : 1 2 3 3 2 2 2 1 1 3
VALUE : 5 6 5 3 6 7 2 1 9 0
I want to give a StoredProc a list of values for example ("6,7,2") and it returns me all IDs that have all the given values in this case it would only returns 2
If I wanted to search for those which at least have one of the values I know I could use "IN" but to have all the values i found nothing.
Thank you in advance
Afshin Arefi
In SQL Server 2008 you can use table value parameters.
These allow you to pass in a table of values to a stored procedure and treat it as any other table (use in sub-queries, joins etc).
In terms of the query - if you do use a table value parameter, you can query it for size (how many rows), use IN in conjunction with a GROUP BY on the ID field and a HAVING that counts the number of rows.