1

I am trying to do a project which uses Visifire to display graphed data. It takes in a single DataTable. I need to create an SQL query that searches a date column for a particular month (format is: Friday, 03 November 2017) and then stores how many times that month is repeated. It has to do this for all 12 months. This is done in C# in visual studio. Currently, it displays no data on the line graph.

public DataTable ReadDataMonthlyBooked()
{
    // Declare references (for table, reader and command)
    DataTable monthlyBookedTable = new DataTable();

    SqlDataReader reader;
    SqlCommand command;

    string selectString = "SELECT COUNT (BookingNum) AS Bookings "
                            + "FROM Booking "
                            + "WHERE Booking.EndDate LIKE  'January' "
                            + "AND Booking.EndDate LIKE 'February' "
                            + "AND Booking.EndDate LIKE 'March' "
                            + "AND Booking.EndDate LIKE 'April' "
                            + "AND Booking.EndDate LIKE 'May' "
                            + "AND Booking.EndDate LIKE 'June' "
                            + "AND Booking.EndDate LIKE 'July' "
                            + "AND Booking.EndDate LIKE 'August' "
                            + "AND Booking.EndDate LIKE 'September' "
                            + "AND Booking.EndDate LIKE 'October' "
                            + "AND Booking.EndDate LIKE 'November' "
                            + "AND Booking.EndDate LIKE 'December'";

    try
    {
        // Create a new command
        command = new SqlCommand(selectString, cnMain);         

        // open the connection  
        cnMain.Open();                                          

        command.CommandType = CommandType.Text;                   
        reader = command.ExecuteReader();

        // read data from readerObject and load in table                  
        monthlyBookedTable.Load(reader);
        reader.Close();     //close the reader 
        cnMain.Close();     //close the connection

        return monthlyBookedTable;
    }
    catch (Exception ex)
    {
        return (null);
    }
}

This is the current SQL query I have and I hope its hopelessly wrong with logic errors but I do not know SQL well enough.

Kaval Patel
  • 670
  • 4
  • 20
  • other than you have december in there twice, what is booking.enddate as a type? if its a date what if its storing 1/1/2018 ? then none of your dates will match plus as you have all 12 months listed if it did work then you'd just get a count of all the things, not across each month... – BugFinder Nov 02 '17 at 14:41
  • If it's a date then it doesn't store it as 1/1/2018 (or Jan. 1, 2018) or any other string format - it stores it as a date and the code needs to handle it as a date. – Tom H Nov 02 '17 at 14:42
  • sorry the first december is meant to be January. Booking.Enddate is a nvarchar(50) stored as (Friday, 03 November 2017) – Joshua Weiss Nov 02 '17 at 14:43
  • If `Booking.Enddate` is in fact a date (as the name implies) - then ***why*** are you storing it as `nvarchar(50)`?? Makes **no sense whatsoever** - always use the **most appropriate** datatype - and for a date, that would be `DATE` ..... – marc_s Nov 02 '17 at 14:44
  • A single date will never be like April and May. – paparazzo Nov 02 '17 at 14:45
  • Yeah unfortunately im helping a friend who made the database so I cant change the database. I was wondering if it is possible to do it as a nvarchar using substrings or contains in sql. – Joshua Weiss Nov 02 '17 at 14:48
  • The problem will still remain that you will get a count of ALL the things.. because any date will match Jan-Dec. You can match substrings you can do like '%January%' – BugFinder Nov 02 '17 at 14:48
  • How would I get a count of all occurrences in all the months? – Joshua Weiss Nov 02 '17 at 14:52
  • If it was stored as a date it would be cake [see this](https://stackoverflow.com/questions/14565788/how-to-group-by-month-from-date-field-using-sql)... stored as a string.. you should look at the convert function and hope that text gets converted to the date you wanted – BugFinder Nov 02 '17 at 14:57
  • 1
    You're currently asking for a count that matches EVERY month. You aren't going to get any strings that have every month in them. – Justin Nov 02 '17 at 15:01

3 Answers3

0

The error is in your SQL statement.

SELECT 
    COUNT(BookingNum) AS Bookings 
FROM 
    Booking 
WHERE 
        Booking.EndDate LIKE '%January%',
    AND Booking.EndDate LIKE '%February%',
    AND Booking.EndDate LIKE '%March%',
    AND Booking.EndDate LIKE '%April%',
    AND Booking.EndDate LIKE '%May%',
    AND Booking.EndDate LIKE '%June%',
    AND Booking.EndDate LIKE '%July%',
    AND Booking.EndDate LIKE '%August%', 
    AND Booking.EndDate LIKE '%September%',
    AND Booking.EndDate LIKE '%October%',
    AND Booking.EndDate LIKE '%November%',
    AND Booking.EndDate LIKE '%December%',

You try to get a record where the month is every month in the year at the same time.

If I'm right, you try to get the number of bookings per month.

So it should look something much more like

SELECT 
    SUM(CASE WHEN Booking.EndDate LIKE '%January%' THEN 1 ELSE 0 END) AS JanuaryBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%February%'  THEN 1 ELSE 0 END) AS FebruaryBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%March%'  THEN 1 ELSE 0 END) AS MarchBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%April%'  THEN 1 ELSE 0 END) AS AprilBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%May%' THEN 1 ELSE 0 END) AS MayBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%June%'  THEN 1 ELSE 0 END) AS JuneBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%July%'  THEN 1 ELSE 0 END) AS JulyBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%August%'  THEN 1 ELSE 0 END) AS AugustBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%September%' THEN 1 ELSE 0 END) AS SeptemberBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%October%'  THEN 1 ELSE 0 END) AS OctoberBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%November%'  THEN 1 ELSE 0 END) AS NovemberBookings,
    SUM(CASE WHEN Booking.EndDate LIKE '%December%' THEN 1 ELSE 0 END) AS DecemberBookings
FROM 
    Booking
0

select 'Friday, 03 November 2017'

select cast('03 November 2017' as date)

select SUBSTRING('Friday, 03 November 2017', CHARINDEX(',', 'Friday, 03 November 2017') + 2, 100)

select cast(SUBSTRING('Friday, 03 November 2017', CHARINDEX(',', 'Friday, 03 November 2017') + 2, 100) as date)

select datepart(month, cast(SUBSTRING('Friday, 03 November 2017', CHARINDEX(',', 'Friday, 03 November 2017') + 2, 100) as date))


select datepart(month, cast(Booking.EndDate, CHARINDEX(',', Booking.EndDate) + 2, 100) as date))
     , COUNT (BookingNum) AS Bookings " 
from booking 
group by datepart(month, cast(Booking.EndDate, CHARINDEX(',', Booking.EndDate) + 2, 100) as date))
paparazzo
  • 44,497
  • 23
  • 105
  • 176
0

You'll need a group by, like this

SELECT COUNT(BookingNum) as Bookings, MONTH(EndDate) as Month
FROM Booking
GROUP BY MONTH(EndDate)

But as your EndDate is a varchar, you'll have to extract the month

SELECT COUNT(BookingNum) as Bookings
     , SUBSTRING(EndDate, 
                 CHARINDEX(',',EndDate) + 4, 
                 CHARINDEX(' ',EndDate, CHARINDEX(',',EndDate) + 5) - CHARINDEX(',',EndDate) + 4)
FROM Booking
GROUP BY SUBSTRING(EndDate, 
                 CHARINDEX(',',EndDate) + 4, 
                 CHARINDEX(' ',EndDate, CHARINDEX(',',EndDate) + 5) - CHARINDEX(',',EndDate) + 4)

There may be a better way to do this (cursors maybe?) but basically you want to get the location of the first ',' and add 4 to get the month (assuming the date is always 2 digits like in your example) and then use that as a start index for a search of the first blank (that'll be the end of the month name) and substract the first index we found to get the length fo the month.

So, basically, just change the date to a DATE field or cast it

SELECT COUNT(BookingNum) as Bookings, MONTH(CONVERT(DATE, EndDate)) as Month
FROM Booking
GROUP BY  MONTH(CONVERT(DATE, EndDate))

But I don't know if the format you are using will be interpreted correctly by the engine.

KinSlayerUY
  • 1,903
  • 17
  • 22