Thursday, April 26, 2012

Reviews you can trust

April 25, 2012

No you can't!

If you are like me, most likely you shop from Amazon, Costco Online, and bestbuy.com etc. You get that package in the mail.  You rip open the package.  Before you even learn to use it properly, you write a nice little review with four or five stars about the product you just purchased.  My be, you return it a few days later, because it sucked, update your review and change your rating to just one or two stars.  Then, some jerks come along and click on "did not find it useful" button.  Now you got 3 out 22 people who found your review useful.  Then you find other reviews about the same product with verbiage like, "My wife was looking for a little camera to take on her DC trip and obviously my big SLR was out of question. So we went to a store to do some shopping. blah blah blah."  Guess what, 6 out of 8 people found the review helpful.  You are scratching your head and feeling agitated with those people of lower intelligence, who did not find your objective review useful.  Well, don't feel so bad.  The majority of those reviews are simply bad (including the ones with most helpful votes) or are fake.  I found this dude on Amazon.com, who has been reviewing cameras and buying them like groceries.  This guy purportedly purchased five cameras in April 2012 and wrote reviews about them.  Three of the those cameras were exactly for the same make/model.  I know that this guy will take his reviews offline very soon, so I captured them in this PDF file on April 25, 2012.

Folks, the bottom line is that with so many choices of products and reviewers, many of them fake like our Johnny boy, it is very hard to believe these reviews.  I am not saying that there are no honest reviews (I mean you can always look at mine :).)  Most likely you will ignore a genuinely useful review because not many found it so useful.  Our Johnny boy's friends and family were at work, clicking on "did not find it useful button."  In my humble opinion, websites like Yelp.com, Angieslist.com etc. were created with good intentions but people who want to beat the system are one step ahead already.

So the bottom line is play the Russian Roulette, buy the product based on your instincts, and be a man,  take it up, you know where, and if it hurts, don't yelp about it!

Update:
April 26, 2012: So our friend Johnny bought and wrote review about another camera today.
April 28, 2012: I must have missed it but Johnny bought two cameras on April 26, 2012 and wrote about them.

Wednesday, April 11, 2012

SQL Server script to find table dependencies

If you work with sql server, I am sure you know the pains associated with the referential integrity.  Try deleting a top level row and you soon realize that a dozen related rows need to be deleted too.   I am updating this blog today because a lot of people misunderstood the purpose of finding out the table dependencies.  It is not just about doing the deletes, may be you want to know want to know how deep the rabbit hole is (God, I love this analogy from the Matrix.)  For understanding a complex data structure there is nothing better than doing top to bottom analysis of all related entities (tables.)   A reverse engineering ERD tool like Visio will do the job as well.  My script does the same and you do not need Visio.  The script finds all the referential dependencies for a table.  It needs schema name and the table name. In the example below, I am getting all dependencies for Production.Product table in the AdventureWorks database. The script does not support composite primary keys (primary key containing several columns.)
begin

--  Use this script to find the dependencies of tables.  
--  Set the following two variables.
--  ####################################################
    declare @TableSchema varchar(255)='Production'
    declare @TableName varchar(255)='Product'
--  ####################################################

    declare @nCnt1 int
    declare @nCnt2 int
    declare @Crsr cursor
    declare @PKTable varchar(255)
    declare @Msg varchar(255)
    
    declare @Tab table (
        [Owner] varchar(255),
        PKTable varchar(255),
        PKColumn varchar(255),
        FKOwner varchar(255),
        FKTable varchar(255),
        FKColumn varchar(255),
        Id int identity,
        Priority int)

    set nocount on

    select
        @nCnt1=1
    from
        INFORMATION_SCHEMA.TABLES
    where
        table_name=@TableName and
        table_schema=@TableSchema

    if  @@rowcount=0
    begin
        set @Msg='No table found '+@TableName
        raiserror (@Msg,16,1) with nowait
    end
        
    delete @Tab

    insert into @Tab (
        [Owner],
        PKTable,
        PKColumn)
    SELECT 
        @TableSchema,
        @TableName,
        column_name
    FROM 
        INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC INNER JOIN
        INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU
            ON 
                TC.CONSTRAINT_TYPE = 'PRIMARY KEY' and
                TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME and 
                ku.table_name=@TableName and
                tc.table_schema=@TableSchema and
                ku.table_schema=@TableSchema
    ORDER BY 
        KU.TABLE_NAME, 
        KU.ORDINAL_POSITION

    while 1=1
    begin
        select 
            @nCnt1=Count(*)
        from
            @Tab
        insert into @Tab (
            [Owner],
            PKTable,
            PKColumn,
            FKOwner,
            FKTable,
            FKColumn)
        select 
            pk.table_schema as pkowner,
            pk.table_name as pktable,
            pk.column_name as pkcolumn,
            fk.table_schema as fkowner,
            fk.table_name as fktable,
            fk.column_name as fkcolumn
        from 
            information_schema.REFERENTIAL_CONSTRAINTS c,
            information_schema.KEY_COLUMN_USAGE fk,
            information_schema.KEY_COLUMN_USAGE pk
        where
            c.constraint_schema=fk.constraint_schema and
            c.constraint_name=fk.constraint_name and
            c.unique_constraint_schema=pk.constraint_schema and
            c.unique_constraint_name=pk.constraint_name and
            pk.ordinal_position=fk.ordinal_position and
            pk.table_name in (
                select 
                    PKTable 
                from 
                    @Tab 
                union
                select 
                    FKTable 
                from 
                    @Tab) and 
            not exists (
                select 
                    1
                from
                    @Tab t
                where
                    t.[Owner]=pk.table_schema and
                    t.PKTable=pk.table_name and
                    t.PKColumn=pk.column_name and
                    t.FKOwner=fk.table_schema and
                    t.FKTable=fk.table_name and
                    t.FKColumn=fk.column_name) and
            1=1
        order by
            pk.table_schema,
            pk.table_name,
            pk.ordinal_position
        select 
            @nCnt2=Count(*)
        from
            @Tab
        if  @nCnt1=@nCnt2
            break
    end
    update @Tab set
        [Priority]=[Id]

    update @Tab set
        [Priority]=mx.[Id]
    from
        @Tab t join 
        (
        select
            x.FKTable,
            Max(x.Id) as [Id]
        from
            @Tab x
        group by
            x.FKTable) mx
        on
            mx.FKTable=t.FKTable

    select 
        PKTable,
        PKColumn,
        FKTable,
        FKColumn,
        [Priority]
    from 
        @Tab 
    order by 
        [Priority],
        [Id]

end
go

The following is the output of this script: