Попробуйте решение, используя класс FileReader
:
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
var file = document.querySelector('#files > input[type="file"]').files[0];
getBase64(file); // prints the base64 string
Обратите внимание, что .files[0]
- это тип File
, который является подкассой Blob
, Таким образом, его можно использовать с FileReader
. См. Полный рабочий пример .
Я думаю, что единственное решение с Вашей структурой таблицы состоит в том, чтобы работать с подзапросом:
SELECT *
FROM Thing
WHERE ID IN (SELECT max(ID) FROM Thing
WHERE ThingID IN (1,2,3,4)
GROUP BY ThingID)
(Учитывая самый высокий идентификатор также означает новейшую цену)
Однако я предлагаю, чтобы Вы добавили столбец "IsCurrent", который является 0, если это не последняя цена или 1, если это является последним. Это добавит возможный риск непоследовательных данных, но это ускорит целый процесс много, когда таблица станет больше (если это находится в индексе). Тогда все, что необходимо сделать, к...
SELECT *
FROM Thing
WHERE ThingID IN (1,2,3,4)
AND IsCurrent = 1
ОБНОВЛЕНИЕ
Хорошо, Markus обновил вопрос показать, что идентификатор является uniqueid, не интервалом. Это делает запись запроса еще более сложной.
SELECT T.*
FROM Thing T
JOIN (SELECT ThingID, max(PriceDateTime)
WHERE ThingID IN (1,2,3,4)
GROUP BY ThingID) X ON X.ThingID = T.ThingID
AND X.PriceDateTime = T.PriceDateTime
WHERE ThingID IN (1,2,3,4)
я действительно предложил бы использовать или столбец "IsCurrent" или пошел бы с другим предложением, найденным в ответах, и использовал бы таблицу "текущей цены" и отдельную "ценовую таблицу" истории (который в конечном счете будет самым быстрым, потому что это сохраняет саму таблицу цен маленькой).
(я знаю, что ThingID внизу избыточен. Просто попробуйте, если это быстрее с или без этого "ГДЕ". Не уверенный, какая версия будет быстрее после того, как оптимизатор сделал свою работу.)
Я попробовал бы что-то как следующий подзапрос и забыл бы об изменении Ваших структур данных.
SELECT
*
FROM
Thing
WHERE
(ThingID, PriceDateTime) IN
(SELECT
ThingID,
max(PriceDateTime )
FROM
Thing
WHERE
ThingID IN (1,2,3,4)
GROUP BY
ThingID
)
Редактирование вышеупомянутое является ANSI SQL, и я теперь предполагаю наличие, больше чем один столбец в подзапросе не работает на SQL T. Marius, я не могу протестировать следующее, но попытку;
SELECT
p.*
FROM
Thing p,
(SELECT ThingID, max(PriceDateTime ) FROM Thing WHERE ThingID IN (1,2,3,4) GROUP BY ThingID) m
WHERE
p.ThingId = m.ThingId
and p.PriceDateTime = m.PriceDateTime
другая опция могла бы состоять в том, чтобы изменить дату на строку и конкатенировать с идентификатором, таким образом, у Вас есть только один столбец. Это было бы немного противно все же.
Если бы маршрут подзапроса был слишком медленным, то я посмотрел бы на обработку Ваших ценовых обновлений как контрольный журнал и поддержание таблицы ThingPrice - возможно, поскольку триггер на цене обновляет таблицу:
ThingID int not null,
UpdateID int not null,
PriceDateTime datetime not null,
Price decimal(18,4) not null
первичным ключом просто был бы ThingID, и "UpdateID" является "идентификатором" в Вашей исходной таблице.
Так как Вы используете SQL Server 2005, можно использовать новое (CROSS|OUTTER), ПРИМЕНЯЮТ пункт. ПРИМЕНЯТЬ пункт позволяет нам, Вы присоединяетесь к таблице с табличной функцией.
Для решения проблемы сначала определите табличную функцию для получения вершины n строки от Вещи для определенного идентификатора, заказанная дата:
CREATE FUNCTION dbo.fn_GetTopThings(@ThingID AS GUID, @n AS INT)
RETURNS TABLE
AS
RETURN
SELECT TOP(@n) *
FROM Things
WHERE ThingID= @ThingID
ORDER BY PriceDateTime DESC
GO
и затем используют функцию для получения лучшей 1 записи в запросе:
SELECT *
FROM Thing t
CROSS APPLY dbo.fn_GetTopThings(t.ThingID, 1)
WHERE t.ThingID IN (1,2,3,4,5,6)
волшебство здесь сделано ПРИМЕНЯТЬ пунктом, который применяет функцию к каждой строке в левом наборе результатов тогда, соединения с набором результатов, возвращенным функцией тогда, возвращают набор конечного результата. (Отметьте: чтобы сделать левому соединению нравится, применяют, используют OUTTER, ПРИМЕНЯЮТСЯ, какие возвраты все строки от левой стороны, в то время как КРЕСТ ПРИМЕНЯЮТ возвраты только строки, которые имеют соответствие в правой стороне)
BlaM: Поскольку я еще не могу добавить комментарии (из-за низких точек rept) к даже моим собственным ответам ^^, я отвечу в теле сообщения: - ПРИМЕНЯТЬ пункт даже, если это использует табличные функции, это оптимизировано внутренне SQL Server таким способом, которым это не вызывает функцию для каждой строки в левом наборе результатов, но вместо этого берет внутренний sql от функции и преобразовывает его в пункт соединения с остальной частью запроса, таким образом, производительность эквивалентна или еще лучше (если план выбран прямо SQL-сервером, и дальнейшая оптимизация может быть сделана), чем производительность запроса с помощью подзапросов), и в моем личном опыте ПРИМЕНЯЮТСЯ, не имеет никаких проблем производительности, когда база данных правильно индексируется, и статистические данные актуальны (точно так же, как нормальный запрос с подзапросами ведет себя в таких условиях)
Это зависит от природы того, как Ваши данные будут использоваться, но если старые ценовые данные не будут использоваться почти так же регулярно как данные текущей цены, может быть аргумент здесь в пользу ценовой таблицы истории. Таким образом, устаревшие данные могут быть заархивированы прочь к ценовой таблице истории (вероятно, триггерами), поскольку новые цены входят.
, Как я говорю, в зависимости от Вашей модели доступа, это могло быть опцией.
Я преобразовываю uniqueidentifier в двоичный файл так, чтобы я мог получить МАКСА его. Это должно удостовериться, что Вы не получите дубликаты от нескольких записей с идентичным ThingIDs и PriceDateTimes:
SELECT * FROM Thing WHERE CONVERT(BINARY(16),Thing.ID) IN
(
SELECT MAX(CONVERT(BINARY(16),Thing.ID))
FROM Thing
INNER JOIN
(SELECT ThingID, MAX(PriceDateTime) LatestPriceDateTime FROM Thing
WHERE PriceDateTime >= CAST(FLOOR(CAST(GETDATE() AS FLOAT)) AS DATETIME)
GROUP BY ThingID) LatestPrices
ON Thing.ThingID = LatestPrices.ThingID
AND Thing.PriceDateTime = LatestPrices.LatestPriceDateTime
GROUP BY Thing.ThingID, Thing.PriceDateTime
) AND Thing.ThingID IN (1,2,3,4,5,6)
Так как идентификатор не последователен, я предполагаю, что у Вас есть уникальный индекс на ThingID и PriceDateTime, таким образом, только одна цена может быть новой для данного объекта.
Этот запрос получит все объекты в списке, ЕСЛИ они были оценены сегодня. Если Вы удаляете, где пункт для PriceDate Вы получите последнюю цену независимо от даты.
SELECT *
FROM Thing thi
WHERE thi.ThingID IN (1,2,3,4,5,6)
AND thi.PriceDateTime =
(SELECT MAX(maxThi.PriceDateTime)
FROM Thing maxThi
WHERE maxThi.PriceDateTime >= CAST( CONVERT(varchar(20), GETDATE(), 106) AS DateTime)
AND maxThi.ThingID = thi.ThingID)
Примечание, которое я изменил">" на"> =", так как Вы могли иметь ценовое право в начале дня
Попробуйте это (обеспечил, Вам только нужно последнее цена , не идентификатор или дата и время той цены)
SELECT ThingID, (SELECT TOP 1 Price FROM Thing WHERE ThingID = T.ThingID ORDER BY PriceDateTime DESC) Price
FROM Thing T
WHERE ThingID IN (1,2,3,4) AND DATEDIFF(D, PriceDateTime, GETDATE()) = 0
GROUP BY ThingID